在PHP中,__sleep
和 __wakeup
是两个魔术方法(Magic Methods),它们与对象的序列化和反序列化过程紧密相关。这两个方法允许开发者在对象被序列化(存储或传输)和反序列化(恢复)时执行自定义的代码。
__sleep
__sleep
方法在对象被序列化之前自动调用。它的主要目的是返回一个包含对象中所有应被序列化的属性名称的数组。如果某个属性不需要被序列化,那么它就不应该出现在这个数组中。
php
public function __sleep(): array
{
return ['property1', 'property2', /* ... */];
}
如果 __sleep
方法没有返回任何数组(即返回空数组或者没有返回值),那么PHP将尝试序列化对象中的所有公共属性。如果方法抛出异常,则序列化过程将失败。
__wakeup
__wakeup
方法在对象被反序列化之后自动调用。它的主要目的是重新建立对象可能需要的任何资源,比如数据库连接、文件句柄等,因为这些资源在序列化过程中是不会被保存的。
php
public function __wakeup()
{
// 重新建立资源或执行其他必要的初始化操作
}
区别与用途
- 调用时机 :
__sleep
在序列化之前调用,而__wakeup
在反序列化之后调用。 - 目的 :
__sleep
用于指定哪些属性应该被序列化,而__wakeup
用于在反序列化后恢复对象的状态或重新建立资源。 - 返回值 :
__sleep
必须返回一个数组,而__wakeup
不需要返回任何值。 - 异常处理 :如果
__sleep
抛出异常,序列化将失败;如果__wakeup
抛出异常,它通常会在反序列化后的代码中更早地显现出来,因为反序列化操作本身通常不会捕获这些异常。
示例
下面是一个简单的示例,展示了如何使用 __sleep
和 __wakeup
:
php
class MyClass {
public $property1;
private $property2;
private $databaseConnection;
public function __construct($property1, $property2) {
$this->property1 = $property1;
$this->property2 = $property2;
// 假设这里建立了数据库连接
$this->databaseConnection = new PDO(/* ... */);
}
public function __sleep(): array {
// 只序列化 property1 和 property2,不序列化数据库连接
return ['property1', 'property2'];
}
public function __wakeup() {
// 在反序列化后重新建立数据库连接
$this->databaseConnection = new PDO(/* ... */);
}
}
// 序列化对象
$obj = new MyClass('value1', 'value2');
$serialized = serialize($obj);
// 反序列化对象
$obj2 = unserialize($serialized);
在这个示例中,__sleep
方法确保了只有 $property1
和 $property2
被序列化,而数据库连接则不会被序列化。然后,在反序列化后,__wakeup
方法负责重新建立数据库连接。