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。或者如果 PGSQL_DML_STRING 通过 flags 传递,则在成功时返回一个 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/Array。这些既不安全
// 通过转义,也不安全通过预处理查询。
$res = pg_insert($dbconn, 'post_log', $_POST, PGSQL_DML_ESCAPE);
if (
$res) {
echo
"POST 数据已成功记录\n";
} else {
echo
"用户可能发送了错误的输入\n";
}
?>

参见

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

添加注释

用户贡献的注释 10 个注释

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;

}
?>
skippy at zuavra dot net
19 年前
注意以下事项:pg_insert() 和 pg_update() 会在所有字符型字段中添加斜杠。这使得它们对 SQL 注入非常安全,但也带来了一些不希望有的后果,如下所示

如果您的系统配置为 magic_quotes_gcp=On,并且您使用了 pg_insert() 或 pg_update(),您最终会在字段中得到看起来像是使用 addslashes() 两次的结果。为了解决这个问题,您可以在使用 pg_insert() 或 pg_update() 之前对数据使用 stripslashes()。

还有另一种选择,在我看来更好。为什么在整个代码中都添加斜杠、删除斜杠,还要担心 magic_quotes_gpc 是否开启等等?当您真正需要这些斜杠的地方仅仅是在将数据推送到数据库的时候,为什么还要这样做呢?

所以,为什么不从您的整个代码中删除 addslashes() 和 stripslashes(),并将 magic_quotes_gcp 关闭呢?只要您始终使用 pg_insert() 和 pg_update() 来完成您的数据库工作,您就可以确保 SQL 注入安全,并且摆脱斜杠带来的头痛。
jsnell at e-normous dot com
16 年前
如果您需要模式支持,这个函数可以做与 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));
}
}
phpuser at ego dot gen dot nz
12 年前
此函数不能用于插入仅包含默认值的记录 - 即使用 array() 作为关联数组。
Anonymous
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 会静默失败
mina86 at tlen dot pl
20 年前
下一个版本 :) 我的版本会检查值是布尔值、null、字符串还是数字,如果其中一个值不是,则函数返回 false。null 值将插入为 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) . ")";
}
?>
excalibur at nospam dot icehouse dot net
17 年前
今天在工作中,我将使用此函数遇到的一个问题隔离到我的日期格式化方式。我在代码中分配日期的方式如下

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

PostgreSQL 接受这种格式,正如他们的文档和使用 psql 进行的测试所证实的那样。但是,为了在我的代码中使其正常工作,我不得不进行以下更改

$today = date( "Y-m-d" ); // 也是 ISO 8601 格式
rorezende at hotmail dot com
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;

}
ANDYCHR17 at HOTMAIL dot COM
18 年前
在尝试在 PHP 4.4.0 中运行此函数时遇到了一些问题

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

- 函数返回 false,直到我传递了 PGSQL_DML_EXEC 选项。
Anonymous
15 年前
如果您尝试插入具有错误命名字段的内容,它似乎会静默失败
To Top