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

PHP 序列化完整指南:serialize/unserialize、魔術方法與最佳實踐

     編輯:PHP 綜合知識

序列化核心概念

序列化將變數(特別是物件)轉換為可儲存、可傳輸的字串格式;反序列化則還原為原始結構。PHP 原生 serialize()/unserialize() 支援所有型別,含物件完整狀態。

基本操作

$user = new class {
    public string $name = 'Alice';
    public int $age = 25;
    private string $secret = 'hidden';
};

// 序列化
$serialized = serialize($user);
// 'O:8:"stdClass":3:{s:4:"name";s:5:"Alice";s:3:"age";i:25;s:15:"\0stdClass\0secret";s:6:"hidden";}'

// 儲存至檔案
file_put_contents('user.dat', $serialized);

// 反序列化(需確保類別定義已載入)
$data = file_get_contents('user.dat');
$user = unserialize($data);

物件生命週期魔術方法

方法觸發時機用途回傳值
__sleep()序列化前清理資源、選擇要序列化的屬性string[] 屬性名稱陣列
__wakeup()反序列化後重建資源連線、初始化狀態無
__serialize()序列化前 (PHP 7.4+)自訂序列化資料結構array 任意資料
__unserialize($data)反序列化後 (PHP 7.4+)從自訂資料還原狀態無

__sleep():精準控制序列化內容

class User {
    public $id;
    public $name;
    private $password; // 敏感資料不應序列化
    private $dbConnection; // 資源型別無法序列化
    
    public function __sleep() {
        // 關閉資料庫連線
        if ($this->dbConnection) {
            $this->dbConnection->close();
        }
        // 僅回傳需序列化的屬性名稱
        return ['id', 'name'];
    }
}

__wakeup():還原運行時狀態

class User {
    // ... 屬性定義
    
    public function __wakeup() {
        // 重新建立資料庫連線
        $this->dbConnection = new PDO($this->dsn, $this->user, $this->pass);
        // 觸發延遲載入邏輯
        $this->loadPermissions();
    }
}

現代序列化介面 (PHP 7.4+)

Serializable 介面已棄用,改用 __serialize()/__unserialize():

class DataTransferObject {
    private $data = [];
    private $computedCache = [];
    
    public function __serialize(): array {
        // 僅序列化核心資料,忽略快取
        return ['data' => $this->data];
    }
    
    public function __unserialize(array $data): void {
        $this->data = $data['data'];
        $this->computedCache = []; // 重置快取
    }
}

其他相關魔術方法

方法觸發情境用途
__toString()物件當作字串使用回傳字串表示,如 echo $obj
__invoke()物件當作函數呼叫使物件可呼叫,閉包即實作此方法
__debugInfo()var_dump() 物件自訂除錯輸出內容(隱藏敏感資訊)
class ApiResponse {
    private $data;
    private $token;
    
    public function __toString() {
        return json_encode($this->data);
    }
    
    public function __invoke($key) {
        return $this->data[$key] ?? null;
    }
    
    public function __debugInfo() {
        return ['data' => $this->data, 'token' => '[HIDDEN]'];
    }
}

$resp = new ApiResponse();
$resp->data = ['user' => 'Alice'];
$resp->token = 'secret123';

echo $resp;           // {"user":"Alice"}
echo $resp('user');   // Alice
var_dump($resp);      // token 顯示 [HIDDEN]

⚠️ 安全與效能警示

  • 反序列化風險:unserialize() 會實例化物件並呼叫 __wakeup()/__destruct(),惡意資料可能導致 RCE。絕不反序列化不可信資料,或使用 unserialize($data, ['allowed_classes' => ['User', 'DTO']]) 限制允許類別(PHP 7.0+)。
  • 效能考量:大型物件圖序列化較慢,高頻場景考慮 JSON、MessagePack、Protocol Buffers 等替代格式。
  • 版本相容:類別結構變更可能導致舊序列化資料無法正確還原,建議實作版本遷移邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved