php 图片 byte数组,php – 将图像存储在PostgreSQL数据库的bytea字段中

TL; DR:

删除addslashes($data).这里多余.

双重逃避..两次

$data=fread($p,filesize($fi));

$data=addslashes($data);

$dat= pg_escape_bytea($data);

您读取数据,将其转义为字符串文字,然后将其转换为bytea八进制或十六进制转义.即使pg_escape_bytea是理智的,它也不会那样,但事实并非如此.

PHP的pg_escape_bytea似乎双重转义输出,因此可以将其插入到字符串文字中.这非常难看,但似乎没有一个替代方法不会进行双重转义,所以你似乎无法在PHP中使用参数化语句来实现bytea.你还应该为其他一切做到这一点.

在这种情况下,只需删除从文件读入的数据的addslashes行就足够了.

测试用例显示pg_escape_bytea双重转义(并且总是使用旧的,低效的八进制转义):

# oh-the-horror.php

print pg_escape_bytea("Blah binary\x00\x01\x02\x03\x04 blah");

?>

跑:

php oh-the-horror.php

结果:

Blah binary\\000\\001\\002\\003\\004 blah

看到加倍的反斜杠?那是因为它假设你要将它作为一个字符串插入到SQL中,这是一个非常低效,丑陋和非常糟糕的习惯.但是你似乎没有任何其他选择.

除此之外,这意味着:

pg_unescape_bytea(pg_escape_bytea("\x01\x02\x03"));

…产生错误的结果,因为pg_unescape_bytea实际上与pg_escape_bytea不相反.它也使得无法将pg_escape_bytea的输出作为参数提供给pg_query_params,你必须将其插入.

解码

如果你使用的是现代的PostgreSQL,它可能会默认将bytea_output设置为十六进制.这意味着如果我将数据写入bytea字段然后将其取回,它将看起来像这样:

craig=> CREATE TABLE byteademo(x bytea);

CREATE TABLE

craig=> INSERT INTO byteademo(x) VALUES ('Blah binary\\000\\001\\002\\003\\004 blah');

INSERT 0 1

craig=> SELECT * FROM byteademo ;

x

----------------------------------------------------------------------------

\x426c61682062696e6172795c3030305c3030315c3030325c3030335c30303420626c6168

(1 row)

“嗯,什么”,你可能会说?这很好,它只是PostgreSQL稍微更紧凑的bytea十六进制表示. pg_unescape_bytea将处理它并产生与输出相同的原始字节…如果你有一个现代的PHP和libpq.在旧版本中,您将获得垃圾,并且需要设置bytea_output以逃避pg_unescape_bytea来处理它.

你应该做什么

使用PDO.

它对bytea有理智(ish)支持.

$sth = $pdo->prepare('INSERT INTO mytable(somecol, byteacol) VALUES (:somecol, :byteacol)');

$sth->bindParam(':somecol', 'bork bork bork');

$sth->bindParam(':byteacol', $thebytes, PDO::PARAM_LOB);

$sth->execute();

看到:

您可能还想查看PostgreSQL的lob(大对象)支持,它提供了一个仍然完全事务性的流式可搜索接口.

现在,到我的肥皂盒

如果PHP在“字节字符串”和“文本字符串”类型之间有真正的区别,您甚至不需要pg_escape_bytea,因为数据库驱动程序可以为您完成.这些丑陋都不是必需的.不幸的是,PHP中没有单独的字符串和字节类型.

请尽可能使用PDO和参数化语句.

在你不能的地方,至少使用pg_query_params和参数化语句. PHP的addslashes不是替代品,它效率低,难看,并且不了解数据库特定的转义规则.如果你因为icky历史原因没有使用PDO,你仍然需要手动转义bytea,但其他一切都应该通过参数化语句.

有关pg_query_params的指导:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值