У меня есть простое веб-приложение на PHP, которое принимает изображения значков посредством загрузки файлов и сохраняет их в столбце MEDIUMBLOB.
На моей машине (Windows) плюс два сервера Linux это работает нормально. На третьем сервере Linux вставленное изображение повреждено: не читается после SELECT, а длина данных столбца, сообщаемых функцией MySQL length (), примерно на 40% больше, чем размер загруженного файла.
(Каждый сервер подключается к отдельному экземпляру MySQL.)
Конечно, это заставляет меня задуматься о проблемах кодирования и набора символов. Столбцы BLOB не имеют связанных кодировок, поэтому наиболее вероятным виновником является PDO и его интерпретация значения параметра для этого столбца.
- Я пытался использовать bindValue с PDO :: PARAM_LOB, но безрезультатно.
- Я проверил, что изображения принимаются на сервер правильно (т.е. я читаю их после загрузки без проблем), так что это определенно проблема с DB / PDO.
- Я искал очевидные различия в конфигурации между серверами, но я не эксперт в конфигурации PHP, поэтому я мог что-то пропустить.
Код вставки выглядит примерно так:
$imagedata = file_get_contents($_FILES["icon"]["tmp_name"]);
$stmt = $pdo->prepare('insert into foo (theimage) values (:theimage)');
$stmt->bindValue(':theimage', $imagedata, PDO::PARAM_LOB);
$stmt->execute();
Любая помощь будет по достоинству оценена.
ОБНОВЛЕНИЕ : кодировка MySQL по умолчанию на проблемном сервере - utf8; это латынь1 на других.
Проблема «решается» путем добавления PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"
в конструктор PDO.
Мне кажется, ошибка плохой дизайн: почему кодировка соединения должна иметь какое-либо влияние на данные для двоичного столбца, особенно когда он идентифицирован как двоичный для Сам PDO с PARAM_LOB?
Обратите внимание, что таблицы DB во всех случаях определены как latin1: несовместимы только наборы символов по умолчанию для серверов.