Session 是 Web 應用維持用戶狀態的核心機制,但「如何徹底銷毀 Session」卻常被誤解。本文系統梳理 Session 生命周期、銷毀函數差異、常見誤區,並給出生產環境推薦的標準流程。
Session 並非隨「登入」開始、「關閉瀏覽器」結束。它是 客戶端(Session ID)與服務端(存儲數據)的會話綁定。Session ID 通常透過 Cookie 傳遞,服務端以文件、Redis、數據庫等形式存儲數據。銷毀操作需同時處理 服務端存儲、內存 $_SESSION 超全局變量、客戶端 Cookie 三個層面。
| 函數 | 服務端存儲 | 內存 $_SESSION | Session ID / Cookie |
|---|---|---|---|
session_unset() | 保留 | 釋放所有變量 | 保留 |
session_destroy() | 刪除文件/數據 | 保留(需手動清空) | 釋放 ID,但 Cookie 仍在客戶端 |
unset($_SESSION['key']) | 保留 | 刪除單鍵 | 保留 |
$_SESSION = [] | 保留 | 清空所有鍵值 | 保留 |
unset($_SESSION) 禁用:會銷毀超全局變量本身,導致後續無法註冊新 Session 變量,且無法恢復。session_unset() 在 PHP 5+ 失效:若使用 $_SESSION 超全局陣列(現代 PHP 必然如此),此函數不再生效,建議棄用。session_destroy() 不夠:當前請求的 $_SESSION 仍可讀寫,且客戶端 Cookie 未刪除,下次請求將復活舊 Session。<?php
// 1. 啟動會話(必須先 start 才能操作)
session_start();
// 2. 清空服務端數據與內存變量
$_SESSION = []; // 或 foreach($_SESSION as $k=>$v) unset($_SESSION[$k]);
// 3. 刪除服務端存儲文件/數據
session_destroy();
// 4. 刪除客戶端 Session Cookie(關鍵步驟!)
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]
);
}
// 5. 可選:重新生成新 Session ID 防止固定攻擊
// session_regenerate_id(true);
?>
unset($_SESSION['user_info']) 即可,無需銷毀整個會話。$_SESSION 關鍵字段,調用 session_regenerate_id(true) 更新 ID 防劫持。session_destroy() 會自動調用對應 Handler 的 destroy 方法,確保配置正確即可。Session 銷毀的本質是「三端同步清理」:服務端存儲、PHP 內存、客戶端 Cookie。缺一不可,才算真正登出。