PHPのお勉強!

PHP TOP

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() は、 table_name で指定したテーブルに values の値を挿入します。

flags が指定されている場合、そのオプションと ともに pg_convert()values に適用されます。

デフォルトでは、 pg_insert() は生の値を渡します。 値はエスケープするか、 flagsPGSQL_DML_ESCAPE オプションを指定しなければいけません。 PGSQL_DML_ESCAPE はパラメータや識別子をクォートし、 エスケープします。 よって、テーブル/カラム名は大文字小文字を区別します。

エスケープやプリペアドクエリであっても、 LIKE, JSON, Array, Regex などのクエリを守れない可能性があることに注意してください。 これらのパラメータはコンテクストに応じて処理されるべきです。 たとえば、値をエスケープ/検証する処理を行うことなどです。

パラメータ

connection

PgSql\Connection クラスのインスタンス。

table_name

行を挿入するテーブルの名前。テーブル table_name は、少なくとも values の要素数ぶんのカラムを 保持している必要があります。

values

テーブル table_name のフィールド名をキーに、 挿入する内容を値にもつ配列。

flags

PGSQL_CONV_OPTSPGSQL_DML_NO_CONVPGSQL_DML_ESCAPEPGSQL_DML_EXECPGSQL_DML_ASYNC あるいは PGSQL_DML_STRING を組み合わせた数。 PGSQL_DML_STRINGflags に含まれていた場合、 クエリ文字列が返されます。 PGSQL_DML_NO_CONV あるいは PGSQL_DML_ESCAPE が設定されている場合は、内部的に pg_convert() を呼びません。

戻り値

成功した場合に true を、失敗した場合に false を返します。 flagsPGSQL_DML_STRING が渡された場合は、成功時に文字列を返します。

エラー / 例外

指定したテーブルが無効な場合、ValueError がスローされます。

値やフィールドの型が PostgreSQL の型と一致しない場合、 ValueError または TypeError がスローされます。

変更履歴

バージョン 説明
8.3.0 指定されたテーブルが無効な場合、 ValueError がスローされるようになりました。 これより前のバージョンでは、E_WARNING が発生していました。
8.3.0 値やフィールドの型が PostgreSQL の型と一致しない場合、 ValueError または TypeError がスローされるようになりました。 これより前のバージョンでは、E_WARNING が発生していました。
8.1.0 PgSql\Result クラスのインスタンスを返すようになりました。 これより前のバージョンでは、リソース を返していました。
8.1.0 connection は、PgSql\Connection クラスのインスタンスを期待するようになりました。 これより前のバージョンでは、リソース を期待していました。

例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 data is successfully logged\n";
} else {
echo
"User must have sent wrong inputs\n";
}
?>

参考

  • pg_convert() - 連想配列の値を、SQL 文として実行可能な形式に変換する

add a note

User Contributed Notes 9 notes

up
6
shane at treesandthings dot com
20 years ago
Returns SQL statement, slight improvement on the code from 'rorezende at hotmail dot com'. This version adds bool values correctly.It also checks to make sure there is actually a value in the array before including it in the sql statement. (ie: null values or empty strings won't be added to the sql statement)

<?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;

}
?>
up
1
skippy at zuavra dot net
19 years ago
Beware of the following: pg_insert() and pg_update() are adding slashes to all character-like fields they work with. This makes them SQL injection super-safe, but there are unwanted consequences, as follows:

If you have a regular setup with magic_quotes_gcp=On, and you use pg_insert() or pg_update(), you will end up with fields that look as if you used addslashes() twice. To solve this, you can use stripslashes() on the data just before using it with pg_insert() or pg_update().

There's another alternative, which seems better to me. Why make yourself crazy all over the code, adding slashes, stripping slashes, worrying whether magic_quotes_gpc is on or off and so on and so forth? Why do this, when the only place you actually need those slashes is right when you push the data into the database?

So why not get rid of your addslashes() and stripslashes() from all over your code, and turn magic_quotes_gcp off. As long as you always use pg_insert() and pg_update() to do your DB work, you're SQL-injection safe AND slash-headache free.
up
1
jsnell at e-normous dot com
17 years ago
If you need schema support, this function will do something similar to 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));
}
}
up
1
phpuser at ego dot gen dot nz
13 years ago
This function cannot be used to insert a record with only default values - i.e. with an assoc_array of array()
up
1
Anonymous
3 years ago
$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);

pg_insert fail silently if one or more fields on table2 have different names than on table1
up
0
mina86 at tlen dot pl
20 years ago
Next version :) My version checks whether value is bool, null, string or numeric and if one of the values is not function returns false if not. null values are inserted as NULL, bool as true or false and strings are add-shlashed before adding to query string. Note, that this function is not safe. SQL injection is possible with column names if you use $_POST or something similar as a $array.

<?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) . ")";
}
?>
up
-1
excalibur at nospam dot icehouse dot net
18 years ago
Today at work I isolated a problem I was having with this function to how I was formatting the date. I was assigning the date in my code as follows:

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

This format is acceptable to PostgreSQL, as verified by their documentation and buy tests using psql. However, to make it work in my code, I had to make the following change:

$today = date( "Y-m-d" ); // also ISO 8601 format
up
-3
rorezende at hotmail dot com
21 years ago
Time is money, then I write a function similar to pg_insert in PHP (only output sql statement) :

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;

}
up
-4
ANDYCHR17 at HOTMAIL dot COM
18 years ago
Had a few issues while trying to run this in PHP 4.4.0:

- I could not get it to work with column names that are SQL reserved words (example: desc, order). I was forced to change the column names in order to use the function. I could not put the column names in quotes, because that caused pg_convert() to fail.

- Function was returning false until I passed the PGSQL_DML_EXEC option.