php serialize, unserialize и UTF-8
Сериализация массивов/объектов в PHP - способ преобразования массива в строку для записи, например в БД или любое другое хранилище данных с возможностью дальнейшего чтения/восстановления.
При использовании примеров из мануала (т.к. они, как правило, используют символы английского алфавита), сложностей с кодировками не возникает
serialize(array(1,15.5,"blabla")); // выведет a:3:{i:0;i:1;i:1;d:15.5;i:2;s:6:"blabla";}
И
unserialize('a:3:{i:0;i:1;i:1;d:15.5;i:2;s:6:"blabla";}'); // корректно отработает
десереализация корректно отработает независимо от используемой кодировки.
Русские буквы немного изменяют ситуацию:
serialize(array(1,15.5,"БЛАbla"));
В зависимости от используемой кодировки - выведет (s:9:”БЛАbla”; vs s:6:”БЛАbla”;)
a:3:{i:0;i:1;i:1;d:15.5;i:2;s:9:"БЛАbla";} - для UTF-8
a:3:{i:0;i:1;i:1;d:15.5;i:2;s:6:"БЛАbla";} - для WINDOWS-1251
И попытка выполнить unserialize для строки, которая была получена при сериализации в кодировке, отличной от текущей (кодировки файла) вернёт false без сообщения об ошибке.
Если неизвестно, в какой кодировке исходная строка - можно воспользоваться встроенной функцией PHP mb_detect_encoding (есть мнение, что она не всегда корректно работает, но отличить UTF-8 от не UTF-8 она сможет.. Допуская, что “не-UTF-8″ это 1251 /как правило,именно так и есть на большинстве сайтов рунета, с которыми приходилось иметь дело*/) - вполне рабочий вариант
Решение в общем-то простое, после определения кодировок.. Использовать конвертацию из UTF-8 в WINDOWS-1251 и обратно для сериализованной строки.. а затем, (если нужна другая кодировка) элементы массива (строки или строковые поля объектов) конвертировать обратно..
$serialize_cp1251 = iconv('utf-8','windows-1251',$serialize_utf8);
$unserialize_cp1251 = unserialize($serialize_cp1251);
// теперь в $unserialize_cp1251 массив/объект, у которого строки в кодировке 1251
// по идее неплохо бы обойти рекурсивной функцией, которая преобразует все
// строковые поля из одной кодировки в другую.