Session 依賴 Cookie 儲存 session_id(預設名稱 PHPSESSID),伺服器端以此 ID 為鍵映射儲存資料(檔案/Redis/資料庫)。理解「客戶端持有 ID、伺服器端持有資料」的分離架構,是正確銷毀的前提。
unset($_SESSION):僅銷毀超級全域變數引用,伺服器端資料與客戶端 Cookie 均保留,下次請求依然有效。$_SESSION = [] 或 $_SESSION = null:清空當前請求的陣列內容,但未刪除伺服器端 Session 檔案與客戶端 Cookie。session_destroy():刪除伺服器端儲存,但 $_SESSION 變數在當前請求仍可讀取,客戶端 Cookie 未清除,下次請求會建立新 Session。// 1. 啟動 Session(若未自動啟動)
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// 2. 清空伺服器端 $_SESSION 陣列內容
$_SESSION = [];
// 3. 刪除客戶端 Session Cookie
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure'],
$params['httponly']
);
// 4. 徹底銷毀伺服器端 Session 資料與 ID
session_destroy();
// 5. 可選:重新生成 ID 防止 Session Fixation 攻擊
session_regenerate_id(true);
採用資料庫或 Redis 儲存 Session,並在使用者表維護 current_session_id。登出時更新該欄位為空,中介軟體每請求驗證 Session ID 是否匹配,不匹配則強制登出。
// 登入成功時
$token = bin2hex(random_bytes(32));
$expire = time() + 30 * 24 * 3600; // 30 天
setcookie('remember_token', $token, $expire, '/', '', true, true);
// 資料庫存入 hash(token) 與 user_id 關聯,下次自動登入時驗證並輪換 token
session.cookie_httponly = 1 防 XSS 竊取session.cookie_secure = 1 僅 HTTPS 傳輸session.use_strict_mode = 1 拒絕未初始化的 Session IDsession.cookie_samesite = 'Lax' 或 'Strict' 防 CSRFsession_id(權限變更、登入後)session.gc_maxlifetime 與 session.gc_probabilitySession 銷毀看似簡單,實則涉及客戶端 Cookie、伺服器端儲存、當前請求超級全域變數三個層面。嚴格遵循「清空陣列 → 刪除 Cookie → 銷毀儲存 → 重生 ID」四步驟,並結合安全配置與分散式儲存策略,才能構建健壯的認證體系。