使用 pdo 将图像插入 sql 服务器数据库

Insert image into sql server db with pdo

$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...

有什么不同?我做错了什么吗? 我在 php 5.6.

上使用带有 Microsoft pdo_odbc 驱动程序的 SQL Server 2008R2

第一个 Google 命中 mssql varbinary pdohttps://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); 应该可行吗?

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

发生的事情是 PDO/MSSQL 认为您传递的是它转换为十六进制的二进制数据,因此 0 ASCII 是 30 十六进制,x78, f 就是 66 等等,希望你明白。

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

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