У меня есть следующий сериализованный массив, хранящийся в поле данных longblob MySQL:
a:1:{s:10:"attributes";a:1:{s:13:"Ticket Holder";a:1:{i:0;s:8:"Joe Blow";}}}
В PHP, когда я запрашиваю поле, десериализую его и распечатываю, выводится следующий пустой массив:
Array
(
)
Это оператор создания таблицы:
CREATE TABLE `order` (
`state` varchar(255) CHARACTER SET ascii DEFAULT NULL,
`data` longblob,
`created` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Ваши сериализованные данные недействительны. Вы никогда не должны обрабатывать сериализованные данные вручную.
Строки сериализуются как:
s:<i>:"<s>";
где <i>
целое число, представляющее длину строки <s>
, а также <s>
это строковое значение.
Таким образом, в этом случае действительные данные:
a:1:{s:10:"attributes";a:1:{s:13:"Ticket Holder";a:1:{i:0;s:8:"Joe Blow";}}}
Joe Blow
длина строки равна 8, но в ваших сериализованных строках определено 13.
Увидеть : Структура сериализованной строки PHP
Преобразование столбца в UTF8 в операторе SELECT и его десериализация.
CONVERT (data USING utf8)
Я не уверен, почему это необходимо. Я предполагаю, что это как-то связано с сопоставлением utf8mb4_general_ci.
Спасибо за вашу помощь, ребята!
Основная проблема связана с двоичным кодированием, выполняемым базой данных, и дополнительными байтами, которые она добавляет к сохраненному значению. Это «повреждает» данные, которые извлекаются из базы данных, и вызывает unserialize
терпеть неудачу. Чтобы помочь смягчить эту проблему, вы можете использовать base64_encode
а также base64_decode
что позволит вам безболезненно вставлять и извлекать данные.
// data is encoded before insert
$dataToInsert = base64_encode(serialize($myArray));
// decode the data before unserializing it
$dataToRead = unserialize(base64_decode($longblob));