У меня есть простое веб-приложение PHP, которое принимает изображения значков через загрузку файлов и сохраняет их в столбце MEDIUMBLOB.
На моей машине (Windows) плюс два Linux-сервера это прекрасно работает. На третьем сервере Linux вставленное изображение повреждено: нечитабельно после SELECT, а длина данных столбца, о котором сообщает функция length() MySQL, примерно на 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; это latin1 на других.
Проблема "решена", добавив PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"
в конструктор PDO.
Мне кажется, что ошибка плохой дизайн для меня: почему кодировка соединения влияет на данные для двоичного столбца, особенно когда она была идентифицирована как двоичная для самого PDO с PARAM_LOB?
Обратите внимание, что таблицы БД во всех случаях определяются как latin1: это противоречивые кодировки серверов по умолчанию.