unserialize

Description

unserialize() takes a single serialized variable and
converts it back into a PHP value.

Warning

Do not pass untrusted user input to unserialize().
Unserialization can result in code being loaded and executed due to object
instantiation and autoloading, and a malicious user may be able to exploit
this. Use a safe, standard data interchange format such as JSON (via
json_decode() and json_encode()) if
you need to pass serialized data to the user.

If you need to unserialize externally stored serialized data, consider to
use hash_hmac() for data validation. Make sure data is
not modified by anyone, but you.

Parameters

str

The serialized string.

If the variable being unserialized is an object, after successfully
reconstructing the object PHP will automatically attempt to call the
__wakeup() member
function (if it exists).

Note:
unserialize_callback_func directive

It's possible to set a callback-function which will be called,
if an undefined class should be instantiated during unserializing.
(to prevent getting an incomplete object "__PHP_Incomplete_Class".)
Use your php.ini, ini_set() or .htaccess
to define 'unserialize_callback_func'. Everytime an undefined class
should be instantiated, it'll be called. To disable this feature just
empty this setting.

Either an array of class names which should be
accepted, FALSE to accept no classes, or TRUE to accept all
classes. If this option is defined and
unserialize() encounters an object of a class
that isn't to be accepted, then the object will be instantiated as
__PHP_Incomplete_Class instead.
Omitting this option is the same as defining it as TRUE: PHP
will attempt to instantiate objects of any class.

function mycallback($classname) {// just include a file containing your classdefinition // you get $classname to figure out which classdefinition is required}?>

Notes

Warning

FALSE is returned both in the case of an error and if unserializing
the serialized FALSE value. It is possible to catch this special case by
comparing str with
serialize(false) or by catching the issued
E_NOTICE.

User Contributed Notes 23 notes

Just a note - if the serialized string contains a reference to a class that cannot be instantiated (e.g. being abstract) PHP will immediately die with a fatal error. If the unserialize() statement is preceded with a '@' to avoid cluttering the logs with warns or notices there will be absolutely no clue as to why the script stopped working. Cost me a couple of hours...

When you serialize an object of a class from a particular namespace, the namespace is recorded as part of the serialization. If you decide to change this namespace's name, it can be hard to read in old serialized objects. I.e., suppose you had serialized an object of type foo\A, you change the namespace of your project to goo but otherwise leave the class definition of A unchanged. You would like to be able to unserialize the object as goo\A, instead unserialization will only create a partial object. To fix this in the case where you don't have nested objects in your class definition, you can use the following simple rename function:/** * Used to change the namespace of a serialized php object (assumes doesn't * have nested subobjects) * * @param string $class_name new fully qualified name with namespace * @param string $object_string serialized object * * @return string serialized object with new name */function renameSerializedObject($class_name, $object_string){ /* number of digits in the length of name of the object needs to be less than 12 digits (probably more like 4) for this to work. */ $name_length = intval(substr($object_string, 2, 14)); $name_space_info_length = strlen("O:".$name_length.":") + $name_length + 2; // 2 for quotes; $object_string = 'O:' . strlen($class_name) . ':"'. $class_name.'"' . substr($object_string, $name_space_info_length); return $object_string;}

2. We analyze this and break it down.
__PHP_Incomplete_Class Object tells you there is an object that needs to be declared somehow.
__PHP_Incomplete_Class_Name simply tells you the expected class name. It is just one of the properties for now.

So we have:
a) an unknown object that has a class name SomeObject1 (first class)
b) it has 2 properties, namely obj1property1 and obj2property2
c) obj2property2 is itself an object whose class name is SomeObject2 (the second class)
d) SomeObject2 has two properties, obj2property1 and obj2property2
e) obj2property2 is an array that contains two elements

3. Now that we have an idea of the structure, we shall create class definitions based from it. We will just create properties for now, methods are not required as a minimum.

In the Classes and Objects docs, there is this: In order to be able to unserialize() an object, the class of that object needs to be defined.

Prior to PHP 5.3, this was not an issue. But after PHP 5.3 an object made by SimpleXML_Load_String() cannot be serialized. An attempt to do so will result in a run-time failure, throwing an exception. If you store such an object in $_SESSION, you will get a post-execution error that says this:

Be aware that if useing serialize/unserialize in a serverfarm with both 32bit and 64bit servers you can get unexpected results.

Ex: if you serialize an integer with value of 2147483648 on a 64bit system and then unserialize it on a 32bit system you will get the value -2147483648 instead. This is because an integer on 32bit cannot be above 2147483647 so it wraps.

This will traverse $data looking for any children which are instances of SimpleXMLElement, and will run ->asXML() on them, turning them into a string and making them serializable. Other data will be left alone.

In reply to the earlier post about having to include object definitions *before* using unserialize. There is a workaround for this.

When an object is serialized, the first bit of the string is actually the name of the class. When an unknown object is unserialized, this is maintained as a property. So if you serialize it again, you get back the exact same string as if you'd serialized the original object. Basically, to cut to the point...

When you use sessions, its very important to keep the sessiondata small, due to low performance with unserialize. Every class shoud extend from this class. The result will be, that no null Values are written to the sessiondata. It will increase performance.

On the client side, you can pass in a complex (nested) JavaScript object to the phpSerialize function to get a PHP-style serialized representation. This string can be posted back and directly passed to the unserialize function to yield a representation of the complex object in PHP realm. Use of this technique requires caution on security matters.