当一个对象被序列化,PHP会调用__sleep方法(如果存在的话). 在反序列化一个对象后,PHP 会调用__wakeup方法. 这两个方法都不接受参数. __sleep方法必须返回一个数组,包含需要序列化的属性. PHP会抛弃其它属性的值. 如果没有__sleep方法,PHP将保存所有属性.
在程序执行前,serialize() 函数会首先检查是否存在一个魔术方法 __sleep.如果存在,__sleep()方法会先被调用, 然后才执行序列化(序列化)操作。这个功能可以用于清理对象,并返回一个包含对象中所有变量名称的数组。如果该方法不返回任何内容,则NULL被序列化,导致 一个E_NOTICE错误。与之相反,unserialize()会检查是否存在一个__wakeup方法。如果存在,则在构建好对象之后就会调用 __wakeup方法,可用来预先准备对象数据。
__sleep方法常用于处理对象的数据。同时,如果你有一些很大的对象, 不需要保存,这个功能就很好用。__wakeup经常用在反序列化操作中,例如初始化属性的值。
__sleep方法不能返回父类的私有成员的名字。这样做会产生一个E_NOTICE级别的错误。这时只能父类先实现Serializable接口。
序列化的时候:
1、类的常量以及静态属性将会被丢失,因为它们是属于类的。
2、父类的public属性会保留下来。
如果反序列化了一个未定义的类的对象,得到的对象是__PHP_Incomplete_Class,并指定了未定义类的类名。如果这个时候我们去使用这个反序列化后的不明对象,则会抛出E_NOTICE。
对象的序列化串是以大写的O开始的。
<?php
class Person{
private $name, $age, $sex, $id;
const APP = 'app';
public static $school = 'peking';
public function __construct($name, $age, $sex)
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
$this->id = uniqid();
}
public function __sleep()
{
return ['name', 'age', 'sex'];
}
public function __wakeup()
{
$this->id = uniqid();
}
}
$boy = new Person('rao', 20, 'male');
var_dump($boy);
echo PHP_EOL;
$temp = serialize($boy);
echo $temp . PHP_EOL;
$boy2 = unserialize($temp);
var_dump($boy2);
打印结果: