1. 程式人生 > >PHP學習——27 PHP面向物件(物件的序列化傳輸或儲存一個物件的方法)

PHP學習——27 PHP面向物件(物件的序列化傳輸或儲存一個物件的方法)

所有php裡面的值都可以使用函式serialize()來返回一個包含位元組流的字串來表示。unserialize()函式能夠重新把字串變回php原來的值。 序列化一個物件將會儲存物件的所有變數,但是不會儲存物件的方法,只會儲存類的名字。

為了能夠unserialize()一個物件,這個物件的類必須已經定義過。如果序列化類A的一個物件,將會返回一個跟類A相關,而且包含了物件所有變數值的字串。 如果要想在另外一個檔案中解序列化一個物件,這個物件的類必須在解序列化之前定義,可以通過包含一個定義該類的檔案或使用函式spl_autoload_register()來實現。

物件是沒有對應實體的,程式執行完就消失了,序列化可以儲存物件的所有變數值。

<?php 
// 1.序列化:string serialize ( mixed $value )
// serialize() 返回字串,此字串包含了表示 value 的位元組流,可以儲存於任何地方

// 2.反序列化:mixed unserialize ( string $str )
// unserialize() 對單一的已序列化的變數進行操作,將其轉換回 PHP 的值。 

// 3.__sleep():serialize() 函式會檢查類中是否存在一個魔術方法 __sleep()。
// 如果存在,該方法會先被呼叫,然後才執行序列化操作。此功能可以用於清理物件,
// 並返回一個包含物件中所有應被序列化的變數名稱的陣列。如果該方法未返回任何
// 內容,則 NULL 被序列化,併產生一個 E_NOTICE 級別的錯誤。 

// 4.__wakeup():unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存
// 在,則會先呼叫 __wakeup 方法,預先準備物件需要的資源。 __wakeup()
// 經常用在反序列化操作中,例如重新建立資料庫連線,或執行其它初始化操作。 

class Employee
{
	public $name;
	public $age;
	public $salary;
	public function __construct($name,$age,$salary)
	{
		$this->name = $name;
		$this->age = $age;
		$this->salary = $salary;
	}
	public function __sleep()
  {
  	// 將允許序列化的物件屬性放在一個數組中返回
    return ['name','age'];
  }
  public function __wakeup()
  {
  	// 對反序列化之後的物件進行修改
    $this->salary=0;
  }
}
$em1 = new Employee('Perter',23,5000);
// 1.序列化
// $em1Str = serialize($em1);
// echo '序列化後的值:'.$em1Str;
// 序列化後的值:O:8:"Employee":3:{s:4:"name";s:6:"Perter";s:3:"age";i:23;s:6:"salary";i:5000;}

// 2.增加 __sleep() 方法,規定只有name和age會被序列化
$em1Str = serialize($em1);
echo '序列化後的值:'.$em1Str;
// 序列化後的值:O:8:"Employee":2:{s:4:"name";s:6:"Perter";s:3:"age";i:23;}
echo '<hr>';

// 3.反序列化
// $em2 = unserialize($em1Str);
// echo '反序列化後的值:';
// print_r($em2);
//序列化後的值:Employee Object ( [name] => Perter [age] => 23 [salary] => )
// 由於沒有序列化salary,所以salary沒有值

// 4.增加 __wakeup() 方法,對salary賦值為0
$em2 = unserialize($em1Str);
echo '反序列化後的值:';
print_r($em2);
// 反序列化後的值:Employee Object ( [name] => Perter [age] => 23 [salary] => 0 )
?>