HTTP 是無狀態協定:每個請求獨立,伺服器無法識別兩個請求來自同一用戶。Session 提供伺服器端狀態儲存,透過Session ID 關聯用戶與資料。
| 方式 | 特點 | 適用場景 |
|---|---|---|
| Cookie (預設) | 自動、透明、支援 HttpOnly/Secure/SameSite | 現代瀏覽器、一般 Web 應用 |
| URL 參數 (`?PHPSESSID=...`) | 禁用 Cookie 環境、爬蟲、舊式功能機 | 需 `session.use_trans_sid=1`,安全性較低(日誌洩露、快取汙染) |
| 隱藏表單欄位 | POST 請求傳遞 | 特殊無 Cookie 表單流程 |
| 誤區 | 真相 |
|---|---|
| Session 資料存在 Cookie 裡 | 僅 Session ID 在 Cookie,資料在伺服器端(檔案/Redis/DB)。 |
| `session_destroy()` 立即刪除 `$_SESSION` | 僅刪除伺服器端儲存與 Cookie,當前請求 `$_SESSION` 仍可讀寫,下一請求才失效。 |
| 關閉瀏覽器 Session 就結束 | 伺服器端資料仍存在,直到 GC 清理。用戶重開瀏覽器若 Cookie 已刪,會獲得新 Session ID。 |
| 多頁面共享 Session 需每頁 `session_start()` | 正確:每個需要存取 `$_SESSION` 的腳本必須在輸出前呼叫 `session_start()`。 |
| Session 可儲存任意資源 (資料庫連線、檔案句柄) | 序列化時資源型別會丟失,僅能儲存可序列化資料(純量、陣列、物件實現 `__sleep`/`__wakeup`)。 |
| Session 適用於大量資料儲存 | 單一 Session 建議 < 100KB,大量資料改用快取/資料庫,Session 僅存 ID/權限/閃存等輕量資訊。 |
<?php
// 啟動 (必須在任何輸出前)
session_start();
// 寫入
$_SESSION['user'] = ['id' => 42, 'name' => 'Alice'];
$_SESSION['cart']['items'][] = ['sku' => 'A001', 'qty' => 2];
// 讀取
$userId = $_SESSION['user']['id'] ?? null;
// 刪除單一鍵
unset($_SESSION['cart']);
// 刪除所有 Session 資料
session_unset(); // 僅清空 $_SESSION
session_destroy(); // 刪除伺服器端儲存 + 發送刪除 Cookie
// 重新生成 ID (登入/權限變更後必做)
session_regenerate_id(true); // true = 刪除舊儲存檔
; php.ini 或 .user.ini / FPM pool
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=xxx&database=1&prefix=sess:"
session.gc_maxlifetime = 1800
session.cookie_lifetime = 1800
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
session.use_strict_mode = 1
session.sid_length = 32
session.sid_bits_per_character = 5
Session 是伺服器端狀態容器,以 Session ID 為鑰匙。掌握啟動時機、ID 傳遞、生命週期、GC 機制、安全配置,避開常見誤區,即能正確使用 Session 構建登入態、購物車、多步表單等核心功能。