PHP Session 的過期機制常被誤解。本文深入剖析 session.gc_maxlifetime、垃圾回收機率、Cookie 生命週期三大核心參數的交互關係,並提供從修改 php.ini、程式碼手動控制、到實現「永不過期」的完整方案,幫助開發者精確掌控 Session 生命週期。
| 參數 | 預設值 | 說明 |
|---|---|---|
| session.gc_maxlifetime | 1440 (24分鐘) | Session 資料在伺服器端的最大存活秒數 |
| session.gc_probability | 1 | 垃圾回收觸發機率分子 |
| session.gc_divisor | 1000 | 垃圾回收觸發機率分母(機率 = 分子/分母) |
| session.cookie_lifetime | 0 | 客戶端 Cookie 存活秒數,0 表示瀏覽器關閉即失效 |
| session.use_cookies | 1 | 是否使用 Cookie 傳遞 Session ID |
關鍵認知: Session 過期檢查是機率性觸發,而非即時生效。
1/1000:每 1000 次請求才觸發 1 次 GCgc_divisor = 1,則每次請求都觸發 GC(開發測試用,生產環境會嚴重影響效能)誤區警示: 修改 gc_maxlifetime 後「好像沒生效」,實際是 GC 尚未執行。高流量網站較易觀察到效果,低流量需等待或手動觸發。
; 延長至 24 小時 (86400 秒) session.gc_maxlifetime = 86400 session.gc_probability = 1 session.gc_divisor = 100
// 檢查上次訪問時間,超過 60 秒視為過期
if (!isset($_SESSION['last_access']) || (time() - $_SESSION['last_access']) > 60) {
// 過期處理:銷毀或重導向登入
session_destroy();
header('Location: /login.php');
exit;
}
$_SESSION['last_access'] = time(); // 更新時間戳
優點: 精確到秒、不依賴 GC、共享主機也能用。缺點: 需在每個入口檔案引入。
; 1. 必須使用 Cookie 傳遞 SID session.use_cookies = 1 ; 2. Cookie 極長壽命 (約 31.7 年) session.cookie_lifetime = 999999999 ; 3. 伺服器端資料極長壽命 session.gc_maxlifetime = 99999999
重啟 Apache/Nginx 後生效。前提: 客戶端不清除 Cookie、伺服器不重啟、硬碟不損壞。
session_start();
$_SESSION['count'] = isset($_SESSION['count']) ? $_SESSION['count'] + 1 : 1;
// 從 Cookie 讀取或生成 SID
$PHPSESSID = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : session_id();
session_id($PHPSESSID);
// 將 SID 寫入長效 Cookie (1 年)
setcookie('PHPSESSID', $PHPSESSID, time() + 31536000, '/');
echo "訪問次數: {$_SESSION['count']}";
頁面跳轉後 Session 讀取不到,phpinfo() 顯示 session.use_trans_sid = 0。
關閉透明 SID 支援後,Session ID 不會自動附加在 URL 上,導致跨頁面無法關聯同一 Session。
session.use_trans_sid = 1(需權限)// 每頁開頭 session_id($_GET['PHPSESSID'] ?? $_COOKIE['PHPSESSID'] ?? session_id()); session_start();
output_buffering = On 允許 header 晚輸出var_dump(is_writable(ini_get('session.save_path')));
若回傳 false,需修改 session_save_path 至可寫目錄。
# 每天清理 24 分鐘前的 session 檔案 0 3 * * * find /path/to/sessions -type f -cmin +1440 -delete
| 場景 | 推薦方案 |
|---|---|
| 獨立伺服器、需長期登入 | 方案 3 (修改 php.ini 三項配置) |
| 共享主機、無 php.ini 權限 | 方案 2 (程式碼手動時間戳) + 方案 4 (手動 SID 管理) |
| 高安全性需求 (銀行、後台) | 方案 2 短過期 (15-30 分鐘) + 關鍵操作重新驗證 |
| 叢集部署 | 資料庫/Redis 儲存 Session + 方案 2 控制邏輯 |
理解 GC 機率機制、區分伺服器端與客戶端過期控制,是精確掌控 PHP Session 生命週期的關鍵。