有時候需要把一個對象在網絡上傳輸,為了方便傳輸,可以把整個對象轉化為二進制串,等到達另一端時,再還原為原來的對象,這個過程稱之為串行化(也叫序列化), 就像我們現在想把一輛汽車通過輪船運到美國去,因為汽車的體積比較大,我們可以把汽車拆開成小的部件,然后我們把這些部件通過輪般運到美國去,到了美國再把這些部件組裝回汽車。
有兩種情況我們必須把對象串行化,第一種情況就是把一個對象在網絡中傳輸的時候要將對象串行化,第二種情況就是把對象寫入文件或是數據庫的時候用到串行化。
串行化有兩個過程,一個是串行化,就是把對象轉化為二進制的字符串,我們使用serialize()函數來串行化一個對象,另一個是反串行化,就是把對象轉化的二進制字符串再轉化為對象, 我們使用unserialize()函數來反串行化一個對象。
PHP中serialize()函數的參數為對象名,返回值為一個字符串,Serialize()返回的字符串含義模糊,一般我們不會解析這個串來得到對象的信息,我們只要把返回來的這個字符串傳到網絡另一端或是保存到文件中即可。
PHP中unserialize()函數來反串行化對象,這個函數的參數即為serialize()函數的返回值,輸出當然是重新組織好的對象。
<?
class Person {
// 下面是人的成員屬性
var $name; // 人的名子
var $sex; // 人的性別
var $age; // 人的年齡
// 定義一個構造方法參數為屬性姓名$name、性別$sex和年齡$age進行賦值
function __construct($name = "", $sex = "", $age = "") {
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}
// 這個人可以說話的方法, 說出自己的屬性
function say() {
echo "我的名子叫:" . $this->name . " 性別:" . $this->sex . " 我的年齡是:" . $this->age . "<br>";
}
}
$p1 = new Person("張三", "男", 20);
$p1_string = serialize($p1); // 把一個對象串行化,返一個字符串
echo $p1_string . "<br>"; // 串行化的字符串我們通常不去解析
$p2 = unserialize($p1_string); // 把一個串行化的字符串反串行化形成對象$p2
$p2->say();
?>
上例輸出結果:
O:6:"Person":3:{s:4:"name";s:4:"張三";s:3:"sex";s:2:"男";s:3:"age";i:20;}
我的名子叫:張三 性別:男 我的年齡是:20
在PHP5中有兩個魔術方法__sleep()方法和__wakeup()方法,在對象串行化的時候,會調用一個__sleep()方法來完成一 些睡前的事情;而在重新醒來,即由二進制串重新組成一個對象的時候,則會自動調用PHP的另一個函數__wakeup(),做一些對象醒來就要做的動作。
__sleep()函數不接受任何參數, 但返回一個數組,其中包含需要串行化的屬性。末被包含的屬性將在串行化時被忽略,如果沒有__sleep()方法,PHP將保存所有屬性。
<?
class Person {
// 下面是人的成員屬性
var $name; // 人的名子
var $sex; // 人的性別
var $age; // 人的年齡
// 定義一個構造方法參數為屬性姓名$name、性別$sex和年齡$age進行賦值
function __construct($name = "", $sex = "", $age = "") {
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}
// 這個人可以說話的方法, 說出自己的屬性
function say() {
echo "我的名子叫:" . $this->name . " 性別:" . $this->sex . " 我的年齡是:" . $this->age . "<br>";
}
// 指定串行化時把返回的數組中$name和$age值串行化,忽略沒在數組中的屬性$sex
function __sleep() {
$arr = array("name", "age"); // 此時,屬性$sex將被刪除!!!
return($arr);
}
// 重新生成對象時,並重新賦值$age為40
function __wakeup() {
$this->age = 40;
}
}
$p1 = new Person("張三", "男", 20);
// 把一個對象串行化,返一個字符串,調用了__sleep()方法,忽略沒在數組中的屬性$sex
$p1_string = serialize($p1);
echo $p1_string . "<br>"; // 串行化的字符串我們通常不去解析
$p2 = unserialize($p1_string); // 反串行化形成對象$p2重新賦值$age為40
$p2->say();
?>
上例輸出值為:
O:6:"Person":2:{s:4:"name";s:4:"張三";s:3:"age";i:20;}
我的名子叫:張三 性別: 我的年齡是:40
