序列化物件 - 會話中的對象

注: 在 PHP 3 中,在序列化和解序列化的過程中物件會失去類的關聯。結果的變量是物件類型,但是沒有類和方法,因此就沒什麼用了(就好像一個用滑稽的語法定義的陣列一樣)。

注意

以下訊息僅在 PHP >= 4 中有效。

serialize() 返回一個字串,包括著可以儲存於 PHP 的任何值的位元組流表示。unserialize() 可以用此字串來重建原始的變量值。用序列化來儲存對象可以儲存物件中的所有變量。物件中的函數不會被儲存,只有類的名稱。

要能夠 unserialize() 一個對象,需要定義該對象的類。也就是,若果序列化了 page1.php 中類 A 的對象 $a,將得到一個指向類 A 的字串並包括有所有 $a 中變量的值。若果要在 page2.php 中將其解序列化,重建類 A 的對象 $a,則 page2.php 中必須要出現類 A 的定義。例如可以這樣實現,將類 A 的定義放在一個包括檔案中,並在 page1.php 和 page2.php 都包括此檔案。

<?php
// classa.inc:
  
class {
      var 
$one 1;

      function 
show_one() {
          echo 
$this->one;
      }
  }

// page1.php:
  
include("classa.inc");

  
$a = new A;
  
$s serialize($a);
  
// 將 $s 存放在某處使 page2.php 能夠找到
  
$fp fopen("store""w");
  
fwrite($fp$s);
  
fclose($fp);

// page2.php:
  // 為了標準解序列化需要這一行
  
include("classa.inc");

  
$s implode("", @file("store"));
  
$a unserialize($s);

  
// 現在可以用 $a 對象的 show_one() 函數了
  
$a->show_one();
?>

若果在用會話並使用了 session_register() 來註冊對象,這些物件會在每個 PHP 頁面結束時被自動序列化,並在接下來的每個頁面中自動解序列化。基本上是說這些物件一旦成為會話的一部分,就能在任何頁面中出現。

強烈建議在所有的頁面中都內含這些註冊的對象的類的定義,即使並不是在所有的頁面中都用到了這些類。若果沒有這樣做,一個物件被解序列化了但卻沒有其類的定義,它將失去與之關聯的類並成為 stdClass 的一個物件而完全沒有任何可用的函數,這樣就很沒有用處。

因此若果在以上的例子中 $a 通過運行 session_register("a") 成為了會話的一部分,應該在所有的頁面中包括 classa.inc 檔案,而不只是 page1.php 和 page2.php。