在面向对象编程(OOP)中,序列化(serialize)是将对象的状态转换为可存储或传输的格式的过程。反序列化(unserialize)则是将序列化后的数据重新构建成原始对象的过程。在PHP中,这两个过程分别由__serialize()
和__unserialize()
魔术方法处理。
1. __serialize() 方法
当调用serialize()
函数时,如果被序列化的对象定义了一个魔术方法__serialize()
,那么这个方法会先被调用。该方法应该返回一个包含对象状态的字符串,以便在反序列化时重新构建对象。
例如:
class MyClass {
public $var1;
protected $var2;
public function __construct($var1, $var2) {
$this->var1 = $var1;
$this->var2 = $var2;
}
public function __serialize(): array {
return [
'var1' => $this->var1,
// 不需要序列化受保护的成员,因为它们在反序列化时无法恢复
];
}
}
在上面的例子中,__serialize()
方法返回一个包含公共变量var1
值的数组。受保护的变量var2
未被序列化,因为它们在反序列化时无法恢复。
2. __unserialize() 方法
当调用unserialize()
函数时,如果被反序列化的对象定义了一个魔术方法__unserialize()
,那么这个方法会先被调用。该方法接受一个包含对象状态的数组作为参数,并使用它来重新构建对象。
例如:
class MyClass {
public $var1;
protected $var2;
public function __construct($var1, $var2) {
$this->var1 = $var1;
$this->var2 = $var2;
}
public function __unserialize(array $data): void {
$this->var1 = $data['var1'];
// 受保护的成员无法恢复,需要在反序列化后手动初始化
$this->var2 = null;
}
}
在上面的例子中,__unserialize()
方法使用传入的数组来设置公共变量var1
的值。受保护的变量var2
无法恢复,需要在反序列化后手动初始化。
3. 注意事项
-
__serialize()
和__unserialize()
方法只能被定义为私有成员(private)。 - 如果一个类没有定义
__sleep()
魔术方法,那么在序列化时,所有非静态的公共、受保护和私有属性都会被序列化。如果类中存在不可序列化的成员(例如资源或闭包),则序列化操作将失败。 - 反序列化时,如果传入的数据格式错误或内容与对象的状态不匹配,则会产生警告或导致异常。因此,在实际应用中,需要对输入数据进行有效性检查。