Совместима ли функция сериализации PHP с UTF-8?
-
23-09-2019 - |
Вопрос
У меня есть сайт, с которого я хочу перенести ИСО к UTF-8.
У меня есть запись в базе данных, проиндексированная следующим первичным ключом:
s:22:"Informations générales";
Проблема в том, что теперь (с UTF-8), когда я сериализую строку, я получаю:
s:24:"Informations générales";
(обратите внимание, что размер строки теперь равен количеству байтов, а не длине строки)
Так что это несовместимо с предыдущими записями, отличными от utf8!
Я сделал что-то не так ?Как я могу это исправить?
Спасибо
Решение
Поведение совершенно правильное.Две строки с разными кодировками будут генерировать разные потоки байтов и, следовательно, разные строки сериализации.
Другие советы
Дамп базы данных на Latin1.
В командной строке:
sed -e 's/latin1/utf8/g' -i ./DBNAME.sql
Импортируйте файл, преобразованный в новую базу данных в формате UTF-8.
Используйте скрипт PHP для обновления каждого поля.Сделайте запрос, пройдите по каждому полю и обновите сериализованную строку, используя следующее:
$str = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $str);
После этого я смог использовать unserialize() и все, что работало с UTF-8.
PHP 4 и 5 не имеют встроенной поддержки Unicode;Я считаю, что PHP 6 начинает добавлять больше поддержки Unicode, хотя я не уверен, насколько это полно.
Чтобы десериализовать сериализованный массив в кодировке utf-8:
$array = @unserialize($arrayFromDatabase);
if ($array === false) {
$array = @unserialize(utf8_decode($arrayFromDatabase)); //decode first
$array = array_map('utf8_encode', $array ); // encode the array again
}
Вы не сделали ничего плохого.PHP до версии 6 просто не поддерживает Unicode и как таковой не поддерживает его, если вы не добьетесь этого (т. е. через mbstring
расширение или другие средства).
Здесь мы написали собственную обертку serialize()
чтобы исправить это.Вы также можете перейти к другим методам сериализации, например JSON (с json_encode()
и json_decode()
в PHP начиная с версии 5.2.0).