Интерфейс Serializable

(PHP 5 >= 5.1.0)

Введение

Интерфейс для индивидуальной сериализации.

Классы, которые реализуют этот интерфейс не поддерживают больше __sleep() и __wakeup(). Метод serialize вызывается всякий раз, когда необходима сериализация экземпляру класса. Этот метод не вызывает __destruct() и не имеет никаких побочных действий кроме тех, которые запрограммированы внутри него. Когда данные десериализованы, класс известен и соответствующий метод unserialize() вызывается как конструктор вместо вызова __construct(). Если вам необходимо вызвать стандартный конструктор, вы можете это сделать в этом методе.

Обзор интерфейсов

Serializable {
/* Методы */
abstract public string serialize ( void )
abstract public void unserialize ( string $serialized )
}

Пример #1 Основы использования

<?php
class obj implements Serializable {
    private 
$data;
    public function 
__construct() {
        
$this->data "My private data";
    }
    public function 
serialize() {
        return 
serialize($this->data);
    }
    public function 
unserialize($data) {
        
$this->data unserialize($data);
    }
    public function 
getData() {
        return 
$this->data;
    }
}

$obj = new obj;
$ser serialize($obj);

var_dump($ser);

$newobj unserialize($ser);

var_dump($newobj->getData());
?>

Результатом выполнения данного примера будет что-то подобное:

string(38) "C:3:"obj":23:{s:15:"My private data";}"
string(15) "My private data"

Содержание

Коментарии

Автор:
You can prevent an object getting unserialized by returning NULL. Instead of a serialized object, PHP will return the serialized form of NULL:

<?php
class testNull implements Serializable {
    public function 
serialize() {       
        return 
NULL;
    }
    public function 
unserialize($data) {
    }
}

$obj = new testNull;
$string serialize($obj);
echo 
$string// "N;"
?>

That's perhaps better than throwing exceptions inside of the serialize function if you want to prevent serialization of certain objects.
2011-05-12 09:09:23
http://php5.kiev.ua/manual/ru/class.serializable.html
Serializing child and parent classes:

<?php
class MyClass implements Serializable {
    private 
$data;
   
    public function 
__construct($data) {
       
$this->data $data;
    }
   
    public function 
getData() {
        return 
$this->data;
    }
   
    public function 
serialize() {
        echo 
"Serializing MyClass...\n";
        return 
serialize($this->data);
    }
   
    public function 
unserialize($data) {
        echo 
"Unserializing MyClass...\n";
       
$this->data unserialize($data);
    }
}

class 
MyChildClass extends MyClass {
    private 
$id;
    private 
$name;
   
    public function 
__construct($id$name$data) {
       
parent::__construct($data);
       
$this->id $id;
       
$this->name $name;
    }
   
    public function 
serialize() {
        echo 
"Serializing MyChildClass...\n";
        return 
serialize(
            array(
               
'id' => $this->id,
               
'name' => $this->name,
               
'parentData' => parent::serialize()
            )
        );
    }
   
    public function 
unserialize($data) {
        echo 
"Unserializing MyChildClass...\n";
       
$data unserialize($data);
       
       
$this->id $data['id'];
       
$this->name $data['name'];
       
parent::unserialize($data['parentData']);
    }
   
    public function 
getId() {
        return 
$this->id;
    }
   
    public function 
getName() {
        return 
$this->name;
    }
}

$obj = new MyChildClass(15'My class name''My data');

$serial serialize($obj);
$newObject unserialize($serial);

echo 
$newObject->getId() . PHP_EOL;
echo 
$newObject->getName() . PHP_EOL;
echo 
$newObject->getData() . PHP_EOL;

?>

This will output:

Serializing MyChildClass...
Serializing MyClass...
Unserializing MyChildClass...
Unserializing MyClass...
15
My class name
My data
2012-01-13 11:05:09
http://php5.kiev.ua/manual/ru/class.serializable.html
Автор:
Here's the way you could implement serializable so that *ALL* descendant serialize themselves without the need of re-writing for all descendant the functions serialize() and unserialize().

Note : this will only serialize "visible" properties, this it won't serialize private descendant properties. If you dont want a property of a descendant to be serialized, make it private.

class Pot implements Serializable
{
    protected $_a;
    protected $_b;

    public function serialize()
    {
        return serialize(get_object_vars($this));
    }
    public function unserialize($data)
    {
        $values = unserialize($data);
        foreach ($values as $key=>$value) {
            $this->$key = $value;
        }
    }
}

And now one descendant:

class PotId implements Pot
{
    protected $_k;
}

class Pots implements PotId
{
    protected $_l;
}

$pots = new Pots();

and calling serialize($pots) will serialize all properties ($_a, $_b, $_k, $l).
2014-05-13 19:19:47
http://php5.kiev.ua/manual/ru/class.serializable.html
Автор:
Here's an example how to un-, serialize more than one property:

class Example implements \Serializable
{
    protected $property1;
    protected $property2;
    protected $property3;

    public function __construct($property1, $property2, $property3)
    {
        $this->property1 = $property1;
        $this->property2 = $property2;
        $this->property3 = $property3;
    }

    public function serialize()
    {
        return serialize([
            $this->property1,
            $this->property2,
            $this->property3,
        ]);
    }

    public function unserialize($data)
    {
        list(
            $this->property1,
            $this->property2,
            $this->property3
        ) = unserialize($data);
    }

}
2015-11-05 23:19:42
http://php5.kiev.ua/manual/ru/class.serializable.html
Автор:
My solution that let you serialize inherited objects.
Without specify what need to be serialized.
We want to get rid of PDO object in this example.

abstract class DefaultModel() implements \Serializable
{

    /**
    * @var PDO
    */
    private $pdo;

    /**
     * Serialize object
     * 
     * @return string
     */
    public function serialize()
    {
       
        $serializable = get_object_vars($this);
       
        // unset property name that hold PDO instance
        unset($serializable['pdo']);
       
        return serialize($serializable);
       
    }

    /**
     * Unserialize object
     * 
     * @param string $serialized Serialized object
     * @return DefaultModel
     */
    public function unserialize($serialized)
    {
       
        $unserialized = unserialize($serialized);
       
       // recreate PDO object
        $this->pdo = $this->createDBObject();
       
        if(is_array($unserialized) === true) {
           
            foreach($unserialized as $property => $value) {
               
                $this->{$property} = $value;
               
            }
           
        }
       
    }

}

class RealModel extends DefaultModel
{

    private $myVar;

    public function setMyVar($value)
    {

        $this->myVar = $value;

    }

}

$model = new RealModel();
$model->setMyVar('123456');

$serialized = serialize($model);
$serialized = $model->serialize();   // will also work

print_r($serialized);

$unserialized = unserialize($serialized);

print_r($unserialized);

Hope this help.
2016-08-05 11:56:36
http://php5.kiev.ua/manual/ru/class.serializable.html
Serialized strings differ between instances that implement Serializable and those that don't.

Instances that don't implement Serializable use the Object notation "O:" when serialized, while those that do use the Class notation "C:". Class notation can only be used to unserialize instances that implement Serializable, while the Object notation can be used to unserialize any object.

Because of this, it is sometimes useful to implement the __wakeup() function when implementing Serializable, for instances where you may have a copy of the serialised class before it implemented Serializable (backwards compatible), or when you're expecting a serialized object from an external source, and they use Object notation for maximum compatibility. You can also use __wakeup() to process your unserialize function, or use it to help prevent people trying to bypass your unserialize.

Below is an example of a simple class hierarchy, where A is a standard class, B implements Serializable, and C uses __wakeup() to assist with unserializing it.

<?php
class {
    protected 
$readonly_data true;
    public 
$public_data true;
   
    public function 
__construct$data true ) {
       
$this->public_data $data;
    }
   
    public function 
get_readonly_data() {
        return 
$this->readonly_data;
    }
}

$a = new A;

var_dump$a );
//object(A)#1 (2) {
//  ["readonly_data":protected]=>
//  bool(true)
//  ["public_data"]=>
//  bool(true)
//}
var_dumpserialize$a ) );
//string(63) "O:1:"A":2:{s:16:"*readonly_data";b:1;s:11:"public_data";b:1;}"
?>
Class A outputs the following object, and its serialized string uses the object notation "O:". Please note that there is a null byte "\0" either side of the star*.

Changing the serialised string and unserializing it can cause protected and private values to change.
<?php
var_dump
unserialize"O:1:\"A\":2:{s:16:\"\0*\0readonly_data\";b:0;s:11:\"public_data\";b:0;}" ) );
//object(A)#1 (2) {
//  ["readonly_data":protected]=>
//  bool(false)
//  ["public_data"]=>
//  bool(false)
//}
?>

Class B extends A, and so has the same constructor and properties. It also implements Serializable.
<?php
class extends implements Serializable {
    public function 
serialize() {
        return 
serialize$this->public_data );
    }
   
    public function 
unserialize$data ) {
       
$this->public_data unserialize $data );
       
do_extra_processing_here();
    }
}

$b = new B;

var_dumpserialize$b ) );
// C:1:"B":4:{b:1;}
?>
As well as being a lot shorter, the serialized string uses the Class notation "C:", but you can still unserialize it using the older style notation. Doing this however will completely ignore the unserialize() function, potentially update the wrong information, and the function do_extra_processing_here() from the example above is not called.
<?php
var_dump
unserialize"O:1:\"B\":2:{s:16:\"\0*\0readonly_data\";b:0;s:11:\"public_data\";b:0;}" ) );
//object(B)#1 (2) {
//  ["readonly_data":protected]=>
//  bool(false)
//  ["public_data"]=>
//  bool(false)
//}
?>

Class C extends B, so it's already using the serialize() and unserialize() functions. By implementing the __wakeup() method, we ensure that we are validating the information and performing our do_extra_processing_here() function.
<?php
class extends {
    public function 
__wakeup() {
       
$new = new static;
       
$this->readonly_data $new->get_readonly_data();
       
do_extra_processing_here();
    }
}

var_dumpunserialize"O:1:\"C\":2:{s:16:\"\0*\0readonly_data\";b:0;s:11:\"public_data\";b:0;}" ) );
//object(B)#1 (2) {
//  ["readonly_data":protected]=>
//  bool(true)
//  ["public_data"]=>
//  bool(false)
//}
?>
We can use __wakeup() to revert our readonly data back to what it was, or to add additional processing. You can additionally call __wakeup() from within unserialize() if you need to do the same process regardless of which serialized string notation was used.
2018-01-11 09:27:38
http://php5.kiev.ua/manual/ru/class.serializable.html

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