unserialize
unserialize — создаёт PHP-значение из хранимого представления.
Описание
mixed unserialize (string str)
unserialize() принимает одну сериализованную переменную (см. serialize()) и конвертирует её обратно в РНР-значение. Возвращается конвертированное значение, которое может быть integer, float, string, array или object.
Примечание: можно установить callback-функцийю, которая будет вызываться, если неопределённый/undefined класс должен быть инстанциирован в процессе десериализации (для предотвращения получения неполного object «__PHP_Incomplete_Class»). Используйте ваш php.ini, ini_set() или .htaccess-файл для определения ‘unserialize_callback_func’. Каждый раз, когда undefined класс должен быть инстанциирован, вызывается эта установка. Для отключения этого просто сделайте эту установку пустой.
Пример 1. unserialize_callback_func
$serialized_object='O:1:"a":1:'; ini_set('unserialize_callback_func','mycallback'); // установить вашу callback_function function mycallback($classname) < // просто включите/include файл, содержащий ваше classdefinition // вы получите $classname для показа того, какое classdefinition необходимо >
Пример 2. unserialize()
// Здесь мы используем unserialize() для загрузки данных сессии в // массив $session_data из строки, выбранной из БД. // Этот пример использует одну из строк, описанных с помощью serialize(). $conn = odbc_connect ("webdb", "php", "chicken"); $stmt = odbc_prepare ($conn, "SELECT data FROM sessions WHERE = array ($PHP_AUTH_USER); if (!odbc_execute ($stmt, &$sqldata) || !odbc_fetch_into ($stmt, &$tmp)) < // если выполнение или извлечение не прошло, инициализируется пустой массив $session_data = array(); >else < // мы не должны иметь сериализованных данных в $tmp[0]. $session_data = unserialize ($tmp[0]); if (!is_array ($session_data)) < // если что-то прошло не так, инициализировать пустой массив $session_data = array(); >>
unserialize
unserialize() takes a single serialized variable and converts it back into a PHP value.
Do not pass untrusted user input to unserialize() regardless of the options value of allowed_classes . 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 using hash_hmac() for data validation. Make sure data is not modified by anyone but you.
Parameters
If the variable being unserialized is an object, after successfully reconstructing the object PHP will automatically attempt to call the __unserialize() or __wakeup() methods (if one 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.
Any options to be provided to unserialize() , as an associative array.
Name | Type | Description |
---|---|---|
allowed_classes | mixed | 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. |
max_depth | int | The maximum depth of structures permitted during unserialization, and is intended to prevent stack overflows. The default depth limit is 4096 and can be disabled by setting max_depth to 0 . |
Return Values
The converted value is returned, and can be a bool , int , float , string , array or object .
In case the passed string is not unserializeable, false is returned and E_NOTICE is issued.
Errors/Exceptions
Objects may throw Throwable s in their unserialization handlers.
Changelog
Version | Description |
---|---|
7.4.0 | Added the max_depth element of options to set the maximum depth of structures permitted during unserialization. |
7.1.0 | The allowed_classes element of options ) is now strictly typed, i.e. if anything other than an array or a bool is given, unserialize() returns false and issues an E_WARNING . |
Examples
Example #1 unserialize() example
// Here, we use unserialize() to load session data to the
// $session_data array from the string selected from a database.
// This example complements the one described with serialize().
?php
$conn = odbc_connect ( «webdb» , «php» , «chicken» );
$stmt = odbc_prepare ( $conn , «SELECT data FROM sessions WHERE > );
$sqldata = array( $_SERVER [ ‘PHP_AUTH_USER’ ]);
if (! odbc_execute ( $stmt , $sqldata ) || ! odbc_fetch_into ( $stmt , $tmp )) // if the execute or fetch fails, initialize to empty array
$session_data = array();
> else // we should now have the serialized data in $tmp[0].
$session_data = unserialize ( $tmp [ 0 ]);
if (! is_array ( $session_data )) // something went wrong, initialize to empty array
$session_data = array();
>
>
?>
Example #2 unserialize_callback_func example
ini_set ( ‘unserialize_callback_func’ , ‘mycallback’ ); // set your callback_function
function mycallback ( $classname )
// just include a file containing your class definition
// you get $classname to figure out which class definition is required
>
?>
Notes
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 data with serialize(false) or by catching the issued E_NOTICE .
See Also
- json_encode() — Returns the JSON representation of a value
- json_decode() — Decodes a JSON string
- hash_hmac() — Generate a keyed hash value using the HMAC method
- serialize() — Generates a storable representation of a value
- Autoloading Classes
- unserialize_callback_func
- unserialize_max_depth
- __wakeup()
- __serialize()
- __unserialize()
User Contributed Notes 24 notes
Just some reminder which may save somebody some time regarding the `$options` array:
Say you want to be on the safe side and not allow any objects to be unserialized. My first thought was doing the following:
$lol = unserialize ( $string , false );
// This will generate:
// Warning: unserialize() expects parameter 2 to be array, boolean given
?>
The correct way of doing this is the following:
$lol = unserialize ( $string , [ ‘allowed_classes’ => false ]);
?>
Hope it helps somebody!
Keep in mind that the allowed_classes does not use inheritance, i.e. allowing an interface is not possible and sub-classes won’t pass the check. See https://3v4l.org/tdHfl
For the people who are getting the error
PHP Notice: unserialize(): Error at offset 191 of 285 bytes in .
and are getting the data from a database, Make sure that you have the database set the the correct encoding, I had the database set as latin1_swedish_ci and all of the data looked perfect, Infact when i copied it into a online unserialize it worked fine. I changed the collation to utf8mb4_unicode_ci and all worked fine.
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.
Here’s a simple function to get the class of a serialized string (that is, the type of object that will be returned if it’s unserialized):
function get_serial_class ( $serial ) $types = array( ‘s’ => ‘string’ , ‘a’ => ‘array’ , ‘b’ => ‘bool’ , ‘i’ => ‘int’ , ‘d’ => ‘float’ , ‘N;’ => ‘NULL’ );
$parts = explode ( ‘:’ , $serial , 4 );
return isset( $types [ $parts [ 0 ]]) ? $types [ $parts [ 0 ]] : trim ( $parts [ 2 ], ‘»‘ );
>
?>
I use this when saving a serialized object to a cookie, to make sure it is the right type when I go to unserialize it.
The type names are the same format/case as you would see if you did a var_dump().
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;
>
__PHP_Incomplete_Class Object Demystified
1. First take note of the output. A simple example:
__PHP_Incomplete_Class Object (
[__PHP_Incomplete_Class_Name] => SomeObject1
[obj1property1] => somevalue1 [obj1property2] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => SomeObject2 [obj2property1] => somevalue1 [obj2property2] => Array (
[‘key1’] => somevalue3, [‘key2’] => somevalue4 ) ) )
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.
class SomeObject1 <
public $obj1property1 ;
public $obj1property2 ;
>
class SomeObject2 <
public $obj2property1 ;
public $obj2property2 ;
>
?>
4. Have that accessible to your script and it will solve the __PHP_Incomplete_Class Object problem as far as the output is concerned. Now you will have:
SomeObject1 ( [obj1property1] => somevalue1 [obj1property2] => SomeObject2 ( [obj2property1] => somevalue1 [obj2property2] => Array ( [‘key1’] => somevalue3, [‘key2’] => somevalue4 ) ) )
As you will notice, __PHP_Incomplete_Class Object is gone and replaced by the class name. The property __PHP_Incomplete_Class_Name is also removed.
5. As for the array property obj2property2, we can directly access that and just assume that it is an array and loop through it:
// this will be SomeObject1
$data = unserialize ( $serialized_data );
// this will be SomeObject2
$data2 = $data -> obj1property2 ();
foreach( $data2 -> obj2property2 as $key => $value ):
print $key . ‘ : ‘ . $value . ‘
‘ ;
endforeach;
?>
Outputs:
key1 : somevalue3
key2 : somevalue4
That’s it. You can add more methods on the class declarations for the given properties, provided you keep your original output as basis for the data types.