使用pdo将镜像插入sql server数据库


$stmt=$con->query("insert into tbl(data) values(0x".$data1['hex'].")");

这是sql语句,它工作得很好。值

0xFFD8FFE000104A46494600010101006000600000FFDB00430... 

被存储在数据库中,我检查过了,图像被存储。但我试图做到这一点使用PDO和存储的值是不同的,不显示图像。这是我的代码

$datastring = file_get_contents("image.JPG");
$data1 = unpack("H*hex", $datastring);
$data = '0x'.$data1['hex'];
$stmt=$conp->prepare("insert into tbl(data) values(:data)");
$stmt->bindparam(':data', $data);
$stmt->execute();

数据库

中的值
0x30786666643866666530303031303461343634393436303...

是什么造成了差异?我做错什么了吗?我使用SQL Server 2008R2与微软pdo_odbc驱动程序在php 5.6.

谷歌搜索mssql varbinary pdo: https://social.msdn.microsoft.com/forums/sqlserver/en-US/221dcea2-438d-4a3a-b438-b98bff8f3d57/using-pdostatementbindvalue-to-update-varbinary-fields

$sth->bindParam(1, $pswd, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);

因此,$stmt->bindParam(':data', $data, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);应该起作用?

编辑:啊啊,愚蠢的我:当然这不起作用。你没有传递二进制,你的字符串只是一个任意的ASCII字符串碰巧看起来像十六进制编码的东西。转到这样的站点:http://www.rapidtables.com/convert/number/hex-to-ascii.htm,粘贴您的0x30786666643866666530303031303461343634393436303,转换为ASCII,然后得到什么?0xffd8ffe000104a4649460,你的原始数据。

发生的事情是PDO/MSSQL认为你正在传递二进制数据,它转换为十六进制,所以0 ASCII是30十六进制,x78, f66等等,我希望你明白这个想法。

与您的第一个工作示例的区别是微妙的:您没有在传递的值(0x...)周围加上引号,因此,它被视为十六进制形式的"真正二进制"。在您的PDO方法中,传递的值可以说是由PDO内部"引用",例如防止SQL注入攻击。如果您在第一个示例周围加上引号,您应该得到与PDO相同的结果。

该怎么办?简单地忘记十六进制编码,让odbc驱动程序/MSSQL处理转换。传递$datastring而不是$data,你应该没问题。

最新更新