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

PHP 將物件儲存至 Session:序列化機制與最佳實務

     編輯:PHP 相關知識

PHP Session 原生支援儲存物件,引擎會自動在請求結束時 序列化 物件,下一請求 反序列化 還原。關鍵在於:類別定義必須在 session_start() 之前載入,否則會變成 __PHP_Incomplete_Class 無法存取屬性方法。

核心規則

  1. 類別檔案需在 session_start() 前 require_once。
  2. 物件屬性應為 public 或實作 __sleep/__wakeup 控制序列化行為。
  3. 避免儲存資源型屬性(資料庫連線、檔案控制代碼、cURL handle),序列化會失敗。

完整範例

Person.php(類別定義)

<?php
// Person.php
class Person {
    public string $name;
    public string $email;

    public function __construct(string $name, string $email) {
        $this->name = $name;
        $this->email = $email;
    }

    public function cleanName(): string {
        return preg_replace('/\s+/', ' ', trim($this->name));
    }

    // 選擇性:控制序列化內容
    public function __sleep(): array {
        return ['name', 'email']; // 僅儲存這兩個屬性
    }
    public function __wakeup(): void {
        // 反序列化後初始化(如重新建立資料庫連線)
    }
}
?>

login.php(儲存物件)

<?php
require_once 'Person.php';
session_start();

if (!isset($_SESSION['user'])) {
    $_SESSION['user'] = new Person('Item Raja', 'itemraja@php.net');
}
header('Location: dashboard.php');

dashboard.php(讀取物件)

<?php
require_once 'Person.php'; // 必須在 session_start 前載入!
session_start();

$user = $_SESSION['user'] ?? null;
if ($user instanceof Person) {
    echo "歡迎, {$user->cleanName()} ({$user->email})";
} else {
    header('Location: login.php');
}
?>

進階:實作 Serializable 介面(PHP 5.1+)

class Person implements Serializable {
    // ...
    public function serialize(): string {
        return json_encode(['name' => $this->name, 'email' => $this->email]);
    }
    public function unserialize(string $data): void {
        $arr = json_decode($data, true);
        $this->name = $arr['name'];
        $this->email = $arr['email'];
    }
}

常見錯誤與解決

最佳實務建議

  • 儲存 DTO/VO 物件:純資料物件,無業務邏輯、無資源依賴。
  • 大型狀態改用 Redis/資料庫:Session 僅存識別碼。
  • 版本演進:新增屬性預設值、實作 __wakeup 相容舊資料。

正確運用物件序列化,能讓 Session 攜帶豐富領域模型,簡化控制器邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
現象原因解決
變成 __PHP_Incomplete_Classsession_start 前未載入類別調整 require_once 順序
私有屬性丟失預設序列化包含所有非 static 屬性實作 __sleep 明確列出
資源屬性導致錯誤資源無法序列化__sleep 排除、__wakeup 重建
大型物件佔用 Session 儲存空間序列化後字串過長僅儲存 ID,需時從 DB/快取載入