unserialize

(PHP 4, PHP 5)

unserialize — Creates a PHP value from a stored representation

Описание

mixed unserialize ( string $str )

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

Список параметров

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).

Замечание: 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.

Возвращаемые значения

The converted value is returned, and can be a boolean, integer, float, string, array or object.

In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued.

Список изменений

Версия Описание
4.2.0 The directive unserialize_callback_func directive became available.
4.0.0 When serializing an object, methods are not lost anymore. Please see the Serializing Objects for more information.

Примеры

Пример #1 unserialize() example

<?php
// 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().

$conn odbc_connect("webdb""php""chicken");
$stmt odbc_prepare($conn"SELECT data FROM sessions WHERE id = ?");
$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();
    }
}
?>

Пример #2 unserialize_callback_func example

<?php
$serialized_object
='O:1:"a":1:{s:5:"value";s:3:"100";}';

// unserialize_callback_func directive available as of PHP 4.2.0
ini_set('unserialize_callback_func''mycallback'); // set your callback_function

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

Примечания

Внимание

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.

Смотрите также

Коментарии

A quick note:
If you store a serialized object in a session, you have to include the class _before_ you initialize (session_start()) the session.
2003-10-30 12:02:07
http://php5.kiev.ua/manual/ru/function.unserialize.html
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...

If you use

$_SESSION['my_object'] = unserialize(serialize($_SESSION['my_object']))

then you get back an object of the correct type, even if the session had originally loaded it as an object of type stdClass.
2004-10-23 12:27:58
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
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.
2006-08-09 04:46:36
http://php5.kiev.ua/manual/ru/function.unserialize.html
This little function will check whether the serialized string is well formed. 

PHP < 6 because i'd heard changes will be made in this php-intern function, 
maybe it could be edited easy for it.

<?php

function wd_check_serialization$string, &$errmsg 
{

   
$str 's';
   
$array 'a';
   
$integer 'i';
   
$any '[^}]*?';
   
$count '\d+';
   
$content '"(?:\\\";|.)*?";';
   
$open_tag '\{';
   
$close_tag '\}';
   
$parameter "($str|$array|$integer|$any):($count)" "(?:[:]($open_tag|$content)|[;])";           
   
$preg "/$parameter|($close_tag)/";
    if( !
preg_match_all$preg$string$matches ) ) 
    {           
       
$errmsg 'not a serialized string';
        return 
false;
    }   
   
$open_arrays 0;
    foreach( 
$matches[1] AS $key => $value )
    {
        if( !empty( 
$value ) && ( $value != $array xor $value != $str xor $value != $integer ) ) 
        {
           
$errmsg 'undefined datatype';
            return 
false;
        }
        if( 
$value == $array )
        {
           
$open_arrays++;                               
            if( 
$matches[3][$key] != '{' 
            {
               
$errmsg 'open tag expected';
                return 
false;
            }
        }
        if( 
$value == '' )
        {
            if( 
$matches[4][$key] != '}' 
            {
               
$errmsg 'close tag expected';
                return 
false;
            }
           
$open_arrays--;
        }
        if( 
$value == $str )
        {
           
$aVar ltrim$matches[3][$key], '"' );
           
$aVar rtrim$aVar'";' );
            if( 
strlen$aVar ) != $matches[2][$key] ) 
            {
               
$errmsg 'stringlen for string not match';
                return 
false;
            }
        }
        if( 
$value == $integer )
        {
            if( !empty( 
$matches[3][$key] ) ) 
            {
               
$errmsg 'unexpected data';
                return 
false;
            }
            if( !
is_integer( (int)$matches[2][$key] ) ) 
            {
               
$errmsg 'integer expected';
                return 
false;
            }
        }
    }       
    if( 
$open_arrays != 
    {
       
$errmsg 'wrong setted arrays';
        return 
false;
    }
    return 
true;
}

?>
2006-12-19 07:09:24
http://php5.kiev.ua/manual/ru/function.unserialize.html
When trying to serialize or unserialize recursive arrays or otherwise linked data you might find the undocumented R data type quite useful.

If you want a array like the one produced with
<?
$a 
= array();
$a[0] =& $a;
?>
serialized you can store it using a string simular to this one:
<?
$a 
unserialize("a:1:{i:0;R:1;}");
?>

Both sources will make $a hold an array that self-references itself in index 0.

The argument for R is the index of the created sub-variable of the serialize-string beginning with 1.
2007-03-02 08:20:29
http://php5.kiev.ua/manual/ru/function.unserialize.html
As mentioned in the notes, unserialize returns false in the event of an error and for boolean false. Here is the first solution mentioned, without using error handling:

<?php
function isSerialized($str) {
    return (
$str == serialize(false) || @unserialize($str) !== false);
}

var_dump(isSerialized('s:6:"foobar";')); // bool(true)
var_dump(isSerialized('foobar'));        // bool(false)
var_dump(isSerialized('b:0;'));          // bool(true)
?>
2008-08-14 09:47:33
http://php5.kiev.ua/manual/ru/function.unserialize.html
When dealing with a string which contain "\r", it seems that the length is not evaluated correctly. The following solves the problem for me :

<?php
// remove the \r caracters from the $unserialized string
$unserialized str_replace("\r","",$unserialized);

// and then unserialize()
unserialize($unserialized);
?>
2009-04-07 08:54:42
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
__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.

<?php
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:

<?php

// this will be SomeObject1 
$data unserialize($serialized_data);

// this will be SomeObject2
$data2 $data->obj1property2();

foreach(
$data2->obj2property2 as $key => $value):
         print 
$key.' : '$value .'<br>'
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.
2009-09-10 10:42:15
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
To all who have problem with quoting and slashes when storing serialized data in MySQL: you are probably doing it wrong.

Use e.g. PDO with placeholders and the blob column type, and it will Just Work.
2010-03-09 12:10:29
http://php5.kiev.ua/manual/ru/function.unserialize.html
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):

<?php
function get_serial_class($serial) {
   
$types = array('s' => 'string''a' => 'array''b' => 'bool''i' => 'int''d' => 'float''N;' => 'NULL');
   
   
$parts explode(':'$serial4);
    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().
2010-03-23 22:46:26
http://php5.kiev.ua/manual/ru/function.unserialize.html
Anyone having trouble serializing data with SimpleXMLElement objects stored within it, check this out:

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.

<?php
function exportNestedSimpleXML($data) {
    if (
is_scalar($data) === false) {
        foreach (
$data as $k => $v) {
            if (
$v instanceof SimpleXMLElement) {
               
$v str_replace("&#13;","\r",$v->asXML());
            } else {
               
$v exportNestedSimpleXML($v);
            }

            if (
is_array($data)) {
               
$data[$k] = $v;
            } else if (
is_object($data)) {
               
$data->$k $v;
            }
        }
    }

    return 
$data;
}

$data = array (
   
"baz" => array (
       
"foo" => new stdClass(),
       
"int" => 123,
       
"str" => "asdf",
       
"bar" => new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>'),
    )
);

var_dump($data);
/*array(1) {
  ["baz"]=>
  array(4) {
    ["foo"]=>
    object(stdClass)#3 (0) {
    }
    ["int"]=>
    int(123)
    ["str"]=>
    string(4) "asdf"
    ["bar"]=>
    object(SimpleXMLElement)#4 (1) {
      [0]=>
      string(3) "bar"
    }
  }
}*/

var_dump(exportNestedSimpleXML($data));
/*array(1) {
  ["baz"]=>
  array(4) {
    ["foo"]=>
    object(stdClass)#3 (0) {
    }
    ["int"]=>
    int(123)
    ["str"]=>
    string(4) "asdf"
    ["bar"]=>
    string(54) "<?xml version="1.0" encoding="UTF-8"?>
<foo>bar</foo>
"
  }
}
*/
?>
2011-06-16 20:31:55
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
To check if a string is serialized:

$blSerialized=(@unserialize($sText)||$sText=='b:0;');
2011-08-02 06:49:03
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
a replacement for unserialize that returns whether it worked and populates the unserialized variable by reference:
<?php
function funserialize($serialized, &$into) {
    static 
$sfalse;
    if (
$sfalse === null)
       
$sfalse serialize(false);
   
$into = @unserialize($serialized);
    return 
$into !== false || rtrim($serialized) === $sfalse;//whitespace at end of serialized var is ignored by PHP
}

$s_foo 'b:0;';
var_dump(funserialize($s_foo$foo), $foo);

$s_bar 'bar';
var_dump(funserialize($s_bar$bar), $bar);

$s_foo 'a:0:{};';
var_dump(funserialize($s_foo$foo), $foo);

?>
gives:

bool(true)
bool(false)

bool(false)
bool(false)

bool(true)
array(0) {
}
2011-08-22 23:22:18
http://php5.kiev.ua/manual/ru/function.unserialize.html
I was getting unserialize()  Error at offset error.

If you face similar problem  then use the following procedure

$auctionDetails = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $dataArr[$i]['auction_details'] ); 
$auctionDetails = unserialize($auctionDetails);
2012-03-13 11:12:16
http://php5.kiev.ua/manual/ru/function.unserialize.html
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:

Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0

The entire contents of the session will be lost.  Hope this saves someone some time!

<?php // RAY_temp_ser.php
error_reporting(E_ALL);
session_start();
var_dump($_SESSION);
$_SESSION['hello'] = 'World';
var_dump($_SESSION);

// AN XML STRING FOR TEST DATA
$xml '<?xml version="1.0"?>
<families>
  <parent>
    <child index="1" value="Category 1">Child One</child>
  </parent>
</families>'
;

// MAKE AN OBJECT (GIVES SimpleXMLElement)
$obj SimpleXML_Load_String($xml);

// STORE THE OBJECT IN THE SESSION
$_SESSION['obj'] = $obj;
2013-07-26 16:41:15
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
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...
2013-08-03 16:05:45
http://php5.kiev.ua/manual/ru/function.unserialize.html
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;
}
2015-07-02 18:28:12
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
You can use the following code to use the php 7 unserialize function in php 5.3 and upwards. This adds the $option argument.

<?php

namespace
{

/**
 * PHP 7 unserialize function for PHP 5.3 upwards.
 * Added the $option argument (allowed_classes).
 * See php unserialize manual for more detail.
 **/
function php7_unserialize($str$options = array())
{
  if(
version_compare(PHP_VERSION'7.0.0''>='))
  { return 
unserialize($str$options); }

 
$allowed_classes = isset($options['allowed_classes']) ? 
   
$options['allowed_classes'] : true;
  if(
is_array($allowed_classes) || !$allowed_classes)
  {
   
$str preg_replace_callback(
     
'/(?=^|:)(O|C):\d+:"([^"]*)":(\d+):{/'
      function(
$matches) use ($allowed_classes)
      {
        if(
is_array($allowed_classes) && 
         
in_array($matches[2], $allowed_classes))
        { return 
$matches[0]; }
        else
        {
          return 
$matches[1].':22:"__PHP_Incomplete_Class":'.
            (
$matches[3] + 1).
           
':{s:27:"__PHP_Incomplete_Class_Name";'.
           
serialize($matches[2]);
        }
      },
     
$str
   
);
  }
  unset(
$allowed_classes);
  return 
unserialize($str);
}

// namespace

namespace my_name_space
{
 
/**
   * Use the new php7 unserialize in your namespace without
   * renaming all unserialize(...) function calls to 
   * php7_unserialize(...).
   **/
 
function unserialize($str$options = array())
  { return 
php7_unserialize($str$options); }
}

?>
2016-09-07 00:52:53
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
Talk on Exploiting PHP7 Unserialize here: https://media.ccc.de/v/33c3-7858-exploiting_php7_unserialize
2017-01-02 02:49:09
http://php5.kiev.ua/manual/ru/function.unserialize.html
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:

<?php
$lol 
unserialize($stringfalse);
// This will generate:
// Warning: unserialize() expects parameter 2 to be array, boolean given
?>

The correct way of doing this is the following:
<?php
$lol 
unserialize($string, ['allowed_classes' => false]);
?>

Hope it helps somebody!
2017-10-30 17:30:30
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
If serialize() is the answer, you're almost certainly asking the wrong question.

JSON is widely available. The only thing it does not do, is the very thing that makes serialization immensely dangerous. All it takes is a crafty hacker to pass a crafted payload to a supposedly 'secured' serialize call, for a database driver to be overwritten with malicious code, for example.

Recreate the object. Normally. With actual data, and a source file, not with serialize. To do otherwise is laziness bordering on malice.
2019-03-11 20:36:04
http://php5.kiev.ua/manual/ru/function.unserialize.html
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.
2020-01-13 15:58:38
http://php5.kiev.ua/manual/ru/function.unserialize.html
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
2020-11-27 09:53:36
http://php5.kiev.ua/manual/ru/function.unserialize.html
Автор:
For those who are looking for an efficient solution for handling controversial "FALSE", they can use this function which in case of non-unserializable string, instead of a "FALSE", throws an Exception. Vice versa it returns the unserialized variable.
<?php
   
/**
     * @param string $serializedString
     * @param array $options
     * @return mixed
     * @throws Exception
     */
   
function UnSerialize(string $serializedString, array $options = []) {
       
$_unserialized = @unserialize($serializedString$options);
        if (
$serializedString === serialize(false) || $_unserialized !== false){
            return 
$_unserialized;
        }
        throw new 
Exception("Non-unserializable string");

    }

?>
2022-10-20 12:34:02
http://php5.kiev.ua/manual/ru/function.unserialize.html

    Поддержать сайт на родительском проекте КГБ