这里的文档有些误导。它说“此方法充当对象的析构函数。在该方法之后不会调用 __destruct() 方法”,我认为意图不是说析构函数不会在对象本身运行,而是说析构函数不会在对象本身运行。 /作为序列化过程的一部分/调用。
也就是说,对象在超出范围时仍将像往常一样被析构,但析构函数不会作为对象序列化的一部分被调用。
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
Serializable::serialize — 对象的字符串表示
此函数没有参数。
返回对象的字符串表示或 null
这里的文档有些误导。它说“此方法充当对象的析构函数。在该方法之后不会调用 __destruct() 方法”,我认为意图不是说析构函数不会在对象本身运行,而是说析构函数不会在对象本身运行。 /作为序列化过程的一部分/调用。
也就是说,对象在超出范围时仍将像往常一样被析构,但析构函数不会作为对象序列化的一部分被调用。
我不喜欢这里的糟糕文档,它们错误地声称“serialize(): 此方法充当对象的析构函数。在该方法之后不会调用 __destruct() 方法”。
它们的含义只是 serialize() 不会调用 __destruct()。这是它们唯一的含义。
正在被序列化的对象将继续作为一个普通对象存在。所以你不应该将 serialize() 视为你的析构函数!将你的对象视为用户可能正在使用的仍然存活的副本!
析构函数将始终像往常一样运行,稍后,当你的对象超出范围(或被你强行 unset())时。
带有证明的示例
<?php
class A implements Serializable
{
public $data = [];
public function __destruct()
{
echo "Destruct of A called.\n";
}
public function serialize()
{
printf("- Serialize of %s called.\n", static::class);
return serialize($this->data);
}
public function unserialize($serialized)
{
printf("- Unserialize of %s called.\n", static::class);
$this->data = unserialize($serialized);
}
}
class B extends A
{
public function __destruct()
{
echo "Destruct of B called.\n";
}
}
$a = new A();
$a->data['inner_b'] = new B();
var_dump($a);
echo "-----------------\n";
echo "Calling serialize($a):\n";
$str = serialize($a);
echo "-----------------\n";
echo "End of script shutdown from here on:...\n";
?>
结果
```
object(A)#1 (1) {
["data"]=>
array(1) {
["inner_b"]=>
object(B)#2 (1) {
["data"]=>
array(0) {
}
}
}
}
-----------------
Calling serialize($a)
- Serialize of A called.
- Serialize of B called.
-----------------
End of script shutdown from here on:...
Destruct of A called.
Destruct of B called.
```