$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 с драйвером Microsoft 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);
должно сработать?
Редактировать: Aaaaah, глупый я: конечно, это не работает. Вы не передаете двоичный файл, ваша строка — это просто произвольная строка ASCII, которая выглядит как нечто закодированное в шестнадцатеричном формате. Перейти на сайт, как это: http://www.rapidtables.com/convert/number/hex-to-ascii.htm, вставьте свой 0x30786666643866666530303031303461343634393436303
, конвертировать в ASCII, и что вы получаете? 0xffd8ffe000104a4649460
исходные данные.
Что происходит, так это то, что PDO / MSSQL считает, что вы передаете двоичные данные, которые он преобразует в шестнадцатеричные, поэтому 0
ASCII является 30
шестигранный, x
является 78
, f
является 66
и так далее, я надеюсь, вы поняли идею.
Разница с вашим первым рабочим примером невелика: вы не ставите кавычки вокруг переданного значения (0x...
), следовательно, он рассматривается как «настоящий двоичный файл» в форме hex. В вашем подходе PDO передаваемое значение, так сказать, внутренне «цитируется» PDO, например, предотвратить атаки SQL-инъекций. Если вы поместите кавычки вокруг вашего первого примера, вы получите те же результаты, что и с PDO.
Что делать? Просто забудьте о шестнадцатеричном кодировании и позвольте драйверу odbc / MSSQL обрабатывать преобразования. Проходить $datastring
вместо $data
и ты должен быть в порядке.
Других решений пока нет …