PHP 8.3: unserialize()
: Upgrade E_NOTICE
errors to E_WARNING
PHP provides serialize
and unserialize()
functions to serialize any PHP value (strings, integers, objects, NULL, arrays, Enums, etc.) to a string representation, and recreate the PHP value from that string representation.
$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']
Prior to PHP 8.3, passing an invalid string to the unserialize()
function emitted PHP notices (E_NOTICE
) in certain cases such as syntax errors in the serialized string. This was changed to emit warnings (E_WARNING
) since PHP 8.3 and later. Further, certain error conditions of the serialize()
function are changed to emit E_WARNING
as well.
unserialize("invalid-string");
- PHP Notice: unserialize(): Error at offset 0 of 14 bytes
+ PHP Warning: unserialize(): Error at offset 0 of 14 bytes
Ideally, failing to unserialize a given string should be a hard-failure and should throw an Exception. However, to maintain backwards compatibility and ease the upgrade paths, the error level is increased in PHP 8.3, with future potential in upgrading it to throw exceptions.
Error condition inconsistency Not all
unserialize()
failures were emittingE_NOTICE
errors. For example, unserializing a string that exceeds the maximum depth limit (configured withunserialize_max_depth
INI setting since PHP 7.4) already emits anE_WARNING
. This case continues to issueE_WARNING
errors, and has not changed.
Affected Error Conditions
The following three error conditions that previously emitted an E_NOTICE
are changed to emit E_WARNING
since PHP 8.3:
- Syntax errors (sometimes caused by incorrect serialization handlers) in the passed string
unserialize('invalid string');
- PHP Notice: unserialize(): Error at offset 0 of 12 bytes + PHP Warning: unserialize(): Error at offset 0 of 12 bytes
- Failures in the custom unserialize handlers using
__unserialize
magic method; e.g the__unserialize()
method not returning any valueclass Test { public function __unserialize(array $data) { } // Does not return anything }
- PHP Notice: unserialize(): Unexpected end of serialized data + PHP Warning: unserialize(): Unexpected end of serialized data
-
Returning the same variable twice from
__sleep()
magic method causing a name clashclass Test { public $foo = 'test'; public function __sleep() { return array("foo", "foo"); // Same value returned twice } } serialize(new Test());
- PHP Notice: serialize(): "foo" is returned from __sleep() multiple times + PHP Warning: serialize(): "foo" is returned from __sleep() multiple times
Backwards Compatibility Impact
In PHP 8.0, PHP's default error reporting level was changed to E_ALL. Unless the error_reporting
value was changed in a custom INI file, this should not introduce any new errors apart from the change in the severity.
Custom error handlers that previously ignored E_NOTICE
errors might encounter the new E_WARNING
because of the change in the severity. Rather than adjusting the error handlers to ignore these warnings, it is highly recommended to evaluate the warning and remediate the invalid error condition.
One notable caveat is that the new serialize pattern introduced for PHP 8.1 Enums. Serialized Enums take E:...
format, and cannot be unserialized in PHP versions prior to PHP 8.1.