@denism300

Почему unserialize возвращает пустое значение?

В свойствах ИБ есть составное кастомное поле.
Перед сохранением в базе данные сериализуются так:
public static function onBeforeSave($arUserField, $value)
    {
        if (is_array($value) && isset($value['VALUE']) && $value['VALUE']['NAME'] && $value['VALUE']['VALUE']) {

            $temp_arr = array(
                'NAME' => trim($value['VALUE']['NAME']),
                'VALUE' => trim($value['VALUE']['VALUE']),
            );
            return array('VALUE' => serialize($temp_arr), 'DESCRIPTION' => '');
        }

        return '';
    }

Массив вида:
Array
(
    [NAME] => Тип гостиницы
    [VALUE] => Парк-отель
)

сериализуется в строку
a:2:{s:4:"NAME";s:25:"Тип гостиницы";s:5:"VALUE";s:19:"Парк-отель";}

При этом, количество символов для значений в 2 раза больше, чем символов.
При загрузке из базы в админке значения десериализуются так:
protected static function normalizeValue($value)
    {
        if (is_string($value)) {
            $value = unserialize($value);
        }

        if (!is_array($value)) {
            $value = array(
                'NAME' => '',
                'VALUE' => ''
            );
        }

        return $value;
    }

Все работает.
А когда на фронт-энде пытаюсь десериализовать эту строку, то
$item = unserialize($value)
возвращает пустое значение.
В отладке
if ($item === false) {
    echo "Ошибка десериализации: " . serialize(error_get_last());
}

Ошибка
Ошибка десериализации: a:4:{s:4:"type";i:2;s:7:"message";s:45:"unserialize(): Error at offset 5 of 117 bytes"

Я понимаю, что проблема из-за того, что во фразе "Тип гостиницы" 13 символов, а в сериализованной строке указано как 25. Но возникает 2 вопроса:
1. Почему в админке эта же самая строка десереализуется?
2. Почему сериализация происходит неправильно?

Сайт работает в кодировке UTF-8
  • Вопрос задан
  • 112 просмотров
Пригласить эксперта
Ответы на вопрос 2
@denism300 Автор вопроса
Проблема решилась так:
$item = unserialize(htmlspecialcharsback($value));
Ответ написан
pickHabr
@pickHabr
fullstack разработчик
"Тип гостиницы" 13 символов, а в сериализованной строке указано как 25


Кириллица это мультибайтовые символы, там где у тебя русские буквы там будет занято 2 байта. Типгостиницы - 12 букв * 2 = 24 + 1 пробел = 25.

Почему в админке эта же самая строка десереализуется?


Если у тебя есть один и тот же код, который в разных окружениях работает по разному, то это значит, что либо
1) код все-таки не одинаковый
2) есть различия в настройках окружения (например php.ini, env, конфиги)

unserialize(htmlspecialcharsback($value));


Как тебе уже подсказали, если у тебя проблема решается через htmlspecialcharsback значит где-то до сериализации есть htmlspecialchars которого быть не должнопро который ты не рассказал в вопросе)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы