PHP 8.3: unserialize() обновление ошибки E_NOTICE до E_WARNING

Источник: «PHP 8.3: unserialize(): Upgrade E_NOTICE errors to E_WARNING»
PHP представляет функции serialize() и unserialize() для сериализации любого значения PHP (строки, целые числа, объекты, NULL, массивы, перечисления и т. д.) и восстановление PHP-значения из этого строкового представления.
$data = ['apple', 'banana', 'orange'];
$serialized = serialize($data);
// "a:3:{i:0;s:5:"apple";i:1;s:6:"banana";i:2;s:6:"orange";}"

$restoredData = unserialize($serialized);
// ['apple', 'banana', 'orange']

До версии PHP 8.3 при передаче недопустимой строки функции unserialize() в некоторых случаях, например при синтаксической ошибке в сериализованной строке выдавалось PHP уведомление (E_NOTICE). Начиная с версии PHP 8.3 и в более поздних версиях это было изменено на выдачу предупреждений (E_WARNING). Кроме того, некоторые условия функции serialize() изменены, чтобы тоже выдавать E_WARNING

unserialize("invalid-string");
- PHP Notice:  unserialize(): Error at offset 0 of 14 bytes
+ PHP Warning: unserialize(): Error at offset 0 of 14 bytes

В идеале невозможность десериализации данной строки должна быть серьёзной ошибкой и вызывать исключение. Однако, для обеспечения обратной совместимости и упрощения обновления в PHP 8.3 увеличили уровень ошибки, а в будущем возможно его обновления до вызова исключения.

Несоответствие условий ошибки

Не все ошибки unserialize() вызывали E_NOTICE. Например десериализация строки, которая превышаем максимальный предел глубины (настроенная INI- параметром unserialize_max_depth, начиная с PHP 7.4 ), уже выдаёт E_WARNING. В этом случае продолжает выдаваться E_WARNING без изменений.

Затрагиваемые условия ошибки

Следующие три условия, которые ранее выдавали E_NOTICE, изменены на E_WARNING, начиная с PHP 8.3:

unserialize('invalid string');
- PHP Notice:  unserialize(): Error at offset 0 of 12 bytes
+ PHP Warning: unserialize(): Error at offset 0 of 12 bytes
class Test {
public function __unserialize(array $data) { } // Ничего не возвращает
}
- PHP Notice: unserialize(): Unexpected end of serialized data
+ PHP Warning: unserialize(): Unexpected end of serialized data
class Test {
public $foo = 'test';
public function __sleep() {
return array("foo", "foo"); // Дважды возвращается одно и то же значение
}
}

serialize(new Test());
- PHP Notice: serialize(): "foo" is returned from __sleep() multiple times
+ PHP Warning: serialize(): "foo" is returned from __sleep() multiple times

Влияние обратной совместимости

В PHP 8.0 уровень сообщений об ошибках PHP по умолчанию был изменён на E_ALL. Если значение error_reporting не было изменено в пользовательском INI-файле, это не должно привести к возникновению каких-либо новых ошибок, кроме изменения уровня серьёзности.

Пользовательские обработчики ошибок, которые ранее игнорировали ошибки E_NOTICE, могут столкнуться с новым E_WARNING из-за изменения серьёзности. Вместо того, чтобы настраивать обработчики ошибок для игнорирования этих предупреждений, настоятельно рекомендуется оценить предупреждение и исправить недопустимое состояние ошибки.

Одно важно предостережение заключается в том, что новый шаблон сериализации включает представленные в PHP 8.1 Перечисления (Enums). Сериализованные перечисления принимают формат E:... и не могут быть десериализованы в версиях PHP до PHP 8.1.

Дополнительные материалы

Предыдущая Статья

PHP 8.3: Добавлена функция json_validate

Следующая Статья

Laravel: Рекомендации на 2022 год. Полное руководство