首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP serialize() 與 unserialize() 函數深度解析與實戰應用

     編輯:PHP 相關知識

在 PHP 開發中,數據的序列化與反序列化是處理複雜數據結構存儲與傳輸的核心技術。serialize() 與 unserialize() 這對函數,讓開發者能將陣列、物件等複雜類型轉化為可存儲的字串格式,並在需要時完整還原,極大地簡化了數據持久化與跨進程傳遞的難度。

核心功能與特性

serialize() 能夠處理除 resource 類型外的所有 PHP 數據類型。它返回一個包含字節流的字串,該字串完整保留了原始值的類型與結構。特別值得一提的是,它支援遞歸引用與自引用陣列,序列化過程中會自動保存變量間的引用關係。

unserialize() 則負責將序列化字串還原為 PHP 值。兩者配合使用,構成了 PHP 數據持久化的基礎橋樑。

魔術方法:__sleep() 與 __wakeup()

當序列化物件時,PHP 會嘗試調用物件的 __sleep() 方法(若存在)。這允許物件在序列化前執行清理操作,例如關閉資源連接、只保留必要屬性。__sleep() 必須返回一個陣列,列出需要序列化的屬性名稱。

反之,unserialize() 還原物件時會自動調用 __wakeup() 方法,常用於重新建立資料庫連線、初始化臨時屬性等場景。

<?php
class User {
    public $name;
    public $id; // 臨時 ID,不需持久化
    
    function __construct() {
        $this->id = uniqid();
    }
    
    function __sleep() {
        return array("name"); // 僅序列化 name
    }
    
    function __wakeup() {
        $this->id = uniqid(); // 還原時重新生成 ID
    }
}

$u = new User();
$u->name = "Leon";
$s = serialize($u); // O:4:"User":1:{s:4:"name";s:4:"Leon";}
$u2 = unserialize($s); // $u 與 $u2 的 id 不同
?>

實戰應用場景

1. 複雜數據入庫與緩存

當數據結構較複雜(如多維陣列、物件圖),且該字段非索引、非主鍵、不參與搜索條件時,序列化存儲是極佳選擇。Session、Cookie、文件緩存、數據庫 TEXT 字段均可承載序列化字串。

2. 跨請求傳遞物件狀態

將物件序列化存入 Session 或資料庫,下一次請求反序列化即可恢復完整狀態,無需重新實例化並手動賦值。

3. 簡易任務隊列

將任務物件序列化存入隊列,Worker 進程取出後反序列化執行,實現異步處理。

基礎範例:陣列與物件序列化

<?php
// 陣列序列化
$array = ['key' => 'website', 'value' => 'www.isoji.org'];
$a = serialize($array);
echo $a; // a:2:{s:3:"key";s:7:"website";s:5:"value";s:15:"www.isoji.org";}
unset($array);
$a = unserialize($a);
print_r($a);

// 物件序列化
class dog {
    var $name, $age, $owner;
    function dog($in_name="unnamed", $in_age="0", $in_owner="unknown") {
        $this->name = $in_name;
        $this->age = $in_age;
        $this->owner = $in_owner;
    }
    function getage() { return $this->age * 365; }
    function getname() { return $this->name; }
}

$ourfirstdog = new dog("Rover", 12, "Lisa and Graham");
$dogdisc = serialize($ourfirstdog);
// O:3:"dog":3:{s:4:"name";s:5:"Rover";s:3:"age";i:12;s:5:"owner";s:15:"Lisa and Graham";}

unset($ourfirstdog);
$pet = unserialize($dogdisc);
echo "Our first dog is called " . $pet->getname() . " and is " . $pet->getage() . " days old";
?>

注意事項與最佳實踐

  • 版本兼容性:PHP 3 僅序列化屬性,PHP 4+ 支援屬性與方法同時序列化。
  • 安全風險:反序列化不可信數據可能導致代碼執行漏洞(如 POP 鏈攻擊),生產環境嚴禁 unserialize() 處理用戶輸入。
  • 性能考量:大型數據結構序列化/反序列化有開銷,高頻場景建議改用 JSON、MessagePack 或 igbinary。
  • 編碼一致性:確保序列化與反序列化環境字符編碼一致,避免中文亂碼。

總結

serialize() 與 unserialize() 是 PHP 內建的強大數據持久化工具,配合 __sleep()/__wakeup() 魔術方法,能靈活控制序列化行為。掌握其原理與適用場景,能讓你在 Session 管理、緩存設計、任務隊列等場景中遊刃有餘。但務必牢記安全邊界,絕不反序列化不可信來源的數據。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved