尝试将12字节字符串写入PostgreSQL
我们的代码计算一个$ number。我们不想将其转换为十六进制,用零填充它并将其写入PostgreSQL bytea字段。容易,对吧?
(作为示例)希望它返回:\ x000000002257('\ x'+ 12 bytes) 即,数字8791的左填充HEX表示:
$number = 8791;
$hexnumber = str_pad(dechex($number), 12, '0', STR_PAD_LEFT);
$packed_hex = pack('h*', $hexnumber);
// BOTH of below produce: 000000002257
pg_raise('notice', "hexnumber: ".$hexnumber);
无法获取这些查询的任何来更新bytea,如我所愿。救命啊!
//$query = ("UPDATE blobtest SET destfile = '".$hexnumber."' WHERE pkey = ".$args[0]);
// $query = ("UPDATE blobtest SET destfile = '000000002257' WHERE pkey = ".$args[0]);
// Above produces: \x303030303030303032323537
// (makes sense; it's quoted as a string)
// $query = ("UPDATE blobtest SET destfile = 000000002257 WHERE pkey = ".$args[0]);
// Above produces: ERROR: column "destfile" is of type bytea but expression is of type integer
// $query = ("UPDATE blobtest SET destfile = '8791' WHERE pkey = ".$args[0]);
// Above produces: \x38373931 as expected...
/ $query = ("UPDATE blobtest SET destfile = 8791 WHERE pkey = ".$args[0]);
// Above produces: ERROR: column "destfile" is of type bytea but expression is of type integer
// $query = ("UPDATE blobtest SET destfile = '"."'".$packed_hex."'"."' WHERE pkey = ".$args[0]);
// Above produces: \x only...
$query = ("UPDATE blobtest SET destfile = "."'".$packed_hex."'"." WHERE pkey = ".$args[0]);
// unterminated quoted string at or near "'"
答案 0 :(得分:1)
您似乎忘记了bytea文字的前导\x
。如果$packed_hex
包含000000002257
,您可以写:
$query = ("UPDATE blobtest SET destfile = '\x".$packed_hex."' WHERE pkey = ".$args[0]);
你需要在PostgreSQL 9.0及更低版本(IIRC)上SET bytea_output = 'hex'
以十六进制形式返回bytea而不是icky旧的八进制转义格式。较新版本默认为hex
。
<soapbox>
您的代码显示了一个坏习惯。使用参数化查询来避免SQL注入。您的应用目前可能会生成packed_hex
,但是谁知道以后如何重用此代码。始终使用参数化查询以避免SQL injection。请参阅the PHP manual on SQL injection。</soapbox>
正如所写,你的代码是可悲的,非常不安全。想象一下,如果$args[0]
包含来自恶意用户的NULL);DROP SCHEMA public;--
。你刚刚发送了:
UPDATE blobtest SET destfile = '\000000002257' WHERE pkey = 0);DROP SCHEMA public;--);
到你的数据库,它执行了什么都没做的UPDATE,然后是一个很可能会破坏你的数据库的DROP SCHEMA public;
,然后是一个忽略其余数据的注释。哎呀,splat,你的数据库,bobby tables再次罢工。
这样写得更好:
$stm = pg_prepare($connection, "", "UPDATE blobtest SET destfile = $1 WHERE pkey = $2");
$result = pg_execute($connection, "", array($packed_hex, $args[0]));