請注意,物件的靜態成員不會被序列化。
serialize() 會傳回一個字串,其中包含任何可以儲存在 PHP 中的值的位元組串流表示。 unserialize() 可以使用這個字串來重建原始變數的值。 使用 serialize 來儲存物件會儲存物件中的所有變數。 物件中的方法不會被儲存,只會儲存類別的名稱。
為了能夠 unserialize() 一個物件,需要定義該物件的類別。 也就是說,如果你有一個 A 類別的物件並將其序列化,你會得到一個指向 A 類別的字串,其中包含它所包含的所有變數的值。 如果你想在另一個檔案中能夠將其反序列化為 A 類別的物件,則必須先在該檔案中存在 A 類別的定義。 例如,可以透過將 A 類別的類別定義儲存在 include 檔案中並包含該檔案,或使用 spl_autoload_register() 函式來完成。
<?php
// A.php:
class A {
public $one = 1;
public function show_one() {
echo $this->one;
}
}
// page1.php:
include "A.php";
$a = new A;
$s = serialize($a);
// 將 $s 儲存在 page2.php 可以找到的地方。
file_put_contents('store', $s);
// page2.php:
// 這是為了讓反序列化正常運作。
include "A.php";
$s = file_get_contents('store');
$a = unserialize($s);
// 現在使用 $a 物件的函式 show_one()。
$a->show_one();
?>
強烈建議如果應用程式序列化物件,以供稍後在應用程式中使用,則該應用程式應在整個應用程式中包含該物件的類別定義。不這樣做可能會導致物件在沒有類別定義的情況下被反序列化,這將導致 PHP 給予該物件 __PHP_Incomplete_Class_Name 的類別,該類別沒有方法,會使物件無法使用。
因此,如果在上面的範例中,$a 透過在 $_SESSION 超全域陣列中新增一個新鍵而成為 session 的一部分,你應該在所有頁面上包含 A.php
檔案,而不僅僅是 page1.php 和 page2.php。
除了上述建議之外,請注意,你也可以使用 __sleep() 和 __wakeup() 方法來掛鉤物件上的序列化和反序列化事件。使用 __sleep() 也允許你只序列化物件屬性的子集。
閱讀此頁面會讓你覺得類別的 `serialize` 和 `unserialize` 方法與 `serialize` 和 `unserialize` 核心函式無關;只有 `__sleep` 和 `__unsleep` 允許你自訂物件的序列化介面。 但是看看 https://php.dev.org.tw/manual/en/class.serializable.php,你會發現有一種更直接的方法來控制如何序列化和反序列化使用者定義的物件。