PHP 8.3: unserialize() обновление ошибки E_NOTICE до E_WARNING
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
- Сбои в пользовательских обработчиках десериализации с использованием магического метода __unserialize, например метод__unserialize()не возвращает ни какого значения
class Test {
    public function __unserialize(array $data) { } // Ничего не возвращает
}- PHP Notice: unserialize(): Unexpected end of serialized data
+ PHP Warning: unserialize(): Unexpected end of serialized data
- Дважды возвращает одну и туже переменную из магического метода __sleep(), вызывая конфликт имён
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.