2024年PHP开发者大会日本站

pg_insert

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

pg_insert 将数组插入到表中

描述

pg_insert(
    PgSql\Connection $connection,
    string $table_name,
    array $values,
    int $flags = PGSQL_DML_EXEC
): PgSql\Result|string|bool

pg_insert()values的值插入到由table_name指定的表中。

如果指定了flags,则将pg_convert()应用于values,并使用指定的标志。

默认情况下,pg_insert() 传递原始值。必须转义值,或者必须在flags中指定PGSQL_DML_ESCAPE标志。PGSQL_DML_ESCAPE 对参数/标识符进行引用和转义。因此,表/列名称区分大小写。

请注意,转义或预处理查询都不能保护LIKE查询、JSON、数组、正则表达式等。这些参数应根据其上下文进行处理,例如转义/验证值。

参数

connection

一个PgSql\Connection实例。

table_name

要向其中插入行的表的名称。table_name表至少必须与values具有相同数量的列。

values

一个array,其键是table_name表中的字段名,其值是要插入的这些字段的值。

flags

任意数量的PGSQL_CONV_OPTSPGSQL_DML_NO_CONVPGSQL_DML_ESCAPEPGSQL_DML_EXECPGSQL_DML_ASYNCPGSQL_DML_STRING组合。如果PGSQL_DML_STRINGflags的一部分,则返回查询字符串。当设置了PGSQL_DML_NO_CONVPGSQL_DML_ESCAPE时,它不会在内部调用pg_convert()

返回值

成功时返回true,失败时返回false。如果通过flags传递了PGSQL_DML_STRING,则成功时返回string

错误/异常

当指定的表无效时,会抛出ValueError异常。

当字段的值或类型与PostgreSQL的类型不匹配时,会抛出ValueErrorTypeError异常。

变更日志

版本 描述
8.3.0 现在当指定的表无效时会抛出ValueError错误;以前会发出E_WARNING警告。
8.3.0 现在当字段的值或类型与PostgreSQL的类型不匹配时会抛出ValueErrorTypeError错误;以前会发出E_WARNING警告。
8.1.0 现在返回一个PgSql\Result实例;以前返回的是一个resource
8.1.0 connection参数现在期望一个PgSql\Connection实例;以前期望的是一个resource

示例

示例 #1 pg_insert() 示例

<?php
$dbconn
= pg_connect('dbname=foo');
// 这在某种程度上是安全的,因为所有值都已转义。
// 但是PostgreSQL支持JSON/数组。这些既不通过转义也不通过预处理查询来保证安全。
$res = pg_insert($dbconn, 'post_log', $_POST, PGSQL_DML_ESCAPE);
if (
$res) {
echo
"POST数据已成功记录\n";
} else {
echo
"用户必须发送了错误的输入\n";
}
?>

参见

  • pg_convert() - 将关联数组值转换为适合SQL语句的格式

添加注释

用户贡献的注释 9条注释

6
shane at treesandthings dot com
20年前
返回SQL语句,对“rorezende at hotmail dot com”的代码进行了轻微改进。此版本正确添加了布尔值。它还会检查数组中是否实际存在值,然后再将其包含在SQL语句中。(即:不会将空值或空字符串添加到SQL语句中)

<?PHP
function db_build_insert($table,$array)
{

$str = "insert into $table ";
$strn = "(";
$strv = " VALUES (";
while(list(
$name,$value) = each($array)) {

if(
is_bool($value)) {
$strn .= "$name,";
$strv .= ($value ? "true":"false") . ",";
continue;
};

if(
is_string($value)) {
$strn .= "$name,";
$strv .= "'$value',";
continue;
}
if (!
is_null($value) and ($value != "")) {
$strn .= "$name,";
$strv .= "$value,";
continue;
}
}
$strn[strlen($strn)-1] = ')';
$strv[strlen($strv)-1] = ')';
$str .= $strn . $strv;
return
$str;

}
?>
1
[email protected]
19年前
注意以下几点:pg_insert() 和 pg_update() 会为所有字符型字段添加反斜杠。这使得它们对SQL注入非常安全,但也会产生一些不想要的后果,如下所示:

如果你的系统配置为 magic_quotes_gpc=On,并且你使用了 pg_insert() 或 pg_update(),最终字段看起来就像你使用了 addslashes() 两次一样。要解决这个问题,你可以在使用 pg_insert() 或 pg_update() 之前,使用 stripslashes() 对数据进行处理。

还有一种更好的方法。为什么要在整个代码中添加反斜杠、去除反斜杠,并担心 magic_quotes_gpc 是否开启等等?当实际上只需要在将数据插入数据库时才需要这些反斜杠时,为什么要这样做呢?

所以,为什么不从你的所有代码中移除 addslashes() 和 stripslashes(),并将 magic_quotes_gpc 关闭呢?只要你始终使用 pg_insert() 和 pg_update() 来处理数据库工作,你就可以保证 SQL 注入安全,并且免受反斜杠的困扰。
1
[email protected]
17年前
如果你需要模式支持,这个函数可以实现类似于 pg_insert 的功能:

function pg_insert_with_schema($connection, $table, $updates)
{
$schema = 'public';
if (strpos($table, '.') !== false)
list($schema, $table) = explode('.', $table);

if (count($updates) == 0) {
$sql = "INSERT INTO $schema.\"$table\" DEFAULT VALUES";
return pg_query($sql);
} else {
$sql = "INSERT INTO $schema.\"$table\" ";

$sql .= '("';
$sql .= join('", "', array_keys($updates));
$sql .= '")';

$sql .= ' values (';
for($i = 0; $i < count($updates); $i++)
$sql .= ($i != 0? ', ':'').'$'.($i+1);
$sql .= ')';
return pg_query_params($connection, $sql, array_values($updates));
}
}
1
[email protected]
12年前
此函数无法用于仅插入默认值(即关联数组为 array())的记录。
1
匿名用户
3年前
$Result = pg_query_params($db,'INSERT INTO table1 (a, b, c) VALUES ($1,$2,$3) RETURNING *', array('1','2','3');
$Row = pg_fetch_assoc($Result);
pg_insert($db, 'table2', $Row);

如果 table2 上的一个或多个字段与 table1 上的字段名称不同,pg_insert 将静默失败。
0
[email protected]
20年前
改进版本 :) 我的版本检查值是否为布尔值、空值、字符串或数字,如果其中一个值不是,则函数返回 false。空值将插入为 NULL,布尔值将插入为 true 或 false,字符串在添加到查询字符串之前将添加反斜杠。请注意,此函数不安全。如果使用 $_POST 或类似内容作为 $array,则可能会发生 SQL 注入。

<?php
function db_build_insert($table, $array) {
if (
count($array)===0) return false;
$columns = array_keys($array);
$values = array_values($array);
unset(
$array);

for (
$i = 0, $c = count($values); $i$c; ++$i) {
if (
is_bool($values[$i])) {
$values[$i] = $values[$i]?'true':'false';
} elseif (
is_null($values[$i])) {
$values[$i] = 'NULL';
} elseif (
is_string($values[$i])) {
$values[$i] = "'" . addslashes($values[$i]) . "'";
} elseif (!
is_numeric($values[$i])) {
return
false;
}
}

return
"INSERT INTO $table ($column_quote" . implode(', ', $columns) .
") VALUES (" . implode(', ', $values) . ")";
}
?>
-1
[email protected]
18年前
今天在工作中,我发现此函数出现问题的原因与日期格式有关。我以前在代码中这样赋值日期:

$today = date( "Ymd" ); // ISO 8601

PostgreSQL 文档和使用 psql 进行的测试都验证了这种格式是可以接受的。但是,为了使其在我的代码中工作,我不得不进行以下更改:

$today = date( "Y-m-d" ); // 也是 ISO 8601 格式
-3
[email protected]
21年前
时间就是金钱,所以我用PHP编写了一个类似于pg_insert的函数(只输出SQL语句)

function db_mount_insert($table,$array) {

$str = "insert into $table (";
while(list($name,$value) = each($array)) {
$str .= "$name,";
}
$str[strlen($str)-1] = ')';
$str .= " values (";
reset($array);
while(list($name,$value) = each($array)) {
if(is_string($value))
$str .= "'$value',";
else
$str .= "$value,";
}
$str[strlen($str)-1] = ')';
$str .= ";" ;

return $str;

}
-4
[email protected]
18年前
在尝试在PHP 4.4.0中运行此代码时遇到了一些问题:

- 我无法使其与作为SQL保留字的列名一起使用(例如:desc、order)。我被迫更改列名才能使用该函数。我不能将列名放在引号中,因为这会导致 pg_convert() 失败。

- 除非我传递 PGSQL_DML_EXEC 选项,否则函数返回 false。
To Top