$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
十六进制,x
是78
, f
是66
等等,我希望你明白这个想法。
与您的第一个工作示例的区别是微妙的:您没有在传递的值(0x...
)周围加上引号,因此,它被视为十六进制形式的"真正二进制"。在您的PDO方法中,传递的值可以说是由PDO内部"引用",例如防止SQL注入攻击。如果您在第一个示例周围加上引号,您应该得到与PDO相同的结果。
该怎么办?简单地忘记十六进制编码,让odbc驱动程序/MSSQL处理转换。传递$datastring
而不是$data
,你应该没问题。