The list of backwards-incompatible changes for PHP 7.4 contain the following note:
Serialization
The o serialization format has been removed. As it is never produced by PHP, this may only break unserialization of manually crafted strings.
(Note that this is referring to a little-o
, not the big-O
format which is used for object serialization.)
It seems this was never generated by PHP's serialize()
function, but the fact that this note exists implies that it was recognised by the unserialize()
function.
I've done a little test fiddle (3v4l.org) which shows this was not simply a synonym for big-O
, which would be one obvious possibility.
The fiddle exposes the changes in PHP by the differences in the error message that is output. In PHP >= 7.4 we get an error at position 0 (where the o
is encountered) whereas prior to 7.4 the error was reported at position 5 (where the data is located). This implies that o
was recognised but the data is in the wrong format, which ties in with what I've already deduced, above.
So, what was the o
serialization format, what did it deserialize to and why did PHP support such a feature if it didn't actually generate it, itself?
Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.
Definition and Usage The serialize() function converts a storable representation of a value. To serialize data means to convert a value to a sequence of bits, so that it can be stored in a file, a memory buffer, or transmitted across a network.
Data serialization is the process of converting an object into a stream of bytes to more easily save or transmit it. The reverse process—constructing a data structure or object from a series of bytes—is deserialization.
To get the POST values from serializeArray in PHP, use the serializeArray() method. The serializeArray( ) method serializes all forms and form elements like the . serialize() method but returns a JSON data structure for you to work with.
Originally, PHP 3 used o:<num_fields>:{<fields>}
to serialize objects.
The following program works in PHP 4.0.0, which can be downloaded from php.net/releases/index.php (the Windows binary still works on Windows 10!):
<?php
var_dump(unserialize('o:0:{}'));
Output:
X-Powered-By: PHP/4.0.0
Content-type: text/html
object(stdClass)(0) {
}
I was able to trace the original implementation of the object serialization format to this commit in 1999. See php3api_var_serialize.
Later that year, the object serialization format was changed to include the classname of the object being serialized in preparation for PHP 4.
This commit changed the serialization format to o:<classname_length>:"<class_name>":<num_fields>:{<fields>}
This made the output of PHP3 and PHP4 incompatible: PHP4 would not have been able to unserialize objects serialized with PHP3.
Therefore, another commit was added that changed o
to O
(lowercase o to uppercase O).
o
was still supported by unserialize()
to unserialize objects serialized with PHP3, but serialize()
did not use o
anymore.
In 2000, the serialization/unserialization code was refactored, resulting in the file we see today.
What probably happened is that the compatibility layer broke somewhere along the way, and no-one cared enough about PHP3 compatibility to fix it. The code in the beginning no longer works with any PHP version released in the last 15 years.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With