這裡的文件有些誤導。其中提到「此方法的作用類似物件的解構函式。在此方法之後,將不會呼叫 __destruct() 方法」,我相信其用意並非指解構函式不會在物件本身上執行,而是解構函式不會在/序列化過程中/被呼叫。
也就是說,物件在超出範圍時仍會正常地被解構,但解構函式不會作為物件序列化的一部分被呼叫。
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
Serializable::serialize — 物件的字串表示
此函式沒有參數。
回傳物件的字串表示或 null
這裡的文件有些誤導。其中提到「此方法的作用類似物件的解構函式。在此方法之後,將不會呼叫 __destruct() 方法」,我相信其用意並非指解構函式不會在物件本身上執行,而是解構函式不會在/序列化過程中/被呼叫。
也就是說,物件在超出範圍時仍會正常地被解構,但解構函式不會作為物件序列化的一部分被呼叫。
我不喜歡這裡糟糕的文件,它錯誤地宣稱「serialize():此方法的作用類似物件的解構函式。在此方法之後,將不會呼叫 __destruct() 方法」。
它們只是想表達 serialize() 並不會呼叫 __destruct()。這就是它們唯一想表達的意思。
正在被序列化的物件將會繼續作為一個正常的物件存在。所以你不應該將 serialize() 視為你的解構函式!應該將你的物件視為使用者可能仍在使用的存活副本!
解構函式將會在稍後物件超出範圍(或者被你強制 unset())時正常執行。
附帶證明的範例
<?php
類別 A 實作 Serializable
{
公開 $data = [];
公開 函式 __destruct()
{
echo "A 的解構函式被呼叫。\n";
}
公開 函式 serialize()
{
printf("- %s 的序列化函式被呼叫。\n", static::class);
return serialize($this->data);
}
公開 函式 unserialize($serialized)
{
printf("- %s 的反序列化函式被呼叫。\n", static::class);
$this->data = unserialize($serialized);
}
}
類別 B 繼承 A
{
公開 函式 __destruct()
{
echo "B 的解構函式被呼叫。\n";
}
}
$a = new A();
$a->data['inner_b'] = new B();
var_dump($a);
echo "-----------------\n";
echo "呼叫 serialize($a):\n";
$str = serialize($a);
echo "-----------------\n";
echo "腳本從此處開始關閉:...\n";
?>
結果
```
物件(A)#1 (1) {
["data"]=>
陣列(1) {
["inner_b"]=>
物件(B)#2 (1) {
["data"]=>
陣列(0) {
}
}
}
}
-----------------
呼叫 serialize($a)
- A 的序列化函式被呼叫。
- B 的序列化函式被呼叫。
-----------------
腳本從此處開始關閉:...
A 的解構函式被呼叫。
B 的解構函式被呼叫。
```