驗證碼明明正確,Session 卻讀不到值?本文歸納 Session 失效的五大主因與對應修正方法,助你快速排錯。
現象:session_start() 無錯誤,但 $_SESSION 永遠為空。
排查:檢查 php.ini 的 session.save_path:
; php.ini
session.save_path = "/var/lib/php/sessions"
; 或 Windows
session.save_path = "D:\php\sessions"
修正:
mkdir -p /var/lib/php/sessionschown www-data:www-data /var/lib/php/sessions && chmod 700 /var/lib/php/sessionsWindows 下同理:建立資料夾並給 IIS_IUSRS 或對應使用者寫入權限。
<?php
// 必須在任何輸出之前
session_start();
if (isset($_POST['captcha'])) {
if ($_SESSION['captcha'] !== $_POST['captcha']) {
die('驗證碼錯誤');
}
}
常見錯誤:include 檔案中重複呼叫、輸出 HTML 後才呼叫、條件判斷漏掉。
session.cookie_domain 設定錯誤)session.cookie_secure = On 但開發環境為 HTTP對策:開發環境設 session.cookie_secure = Off、session.cookie_samesite = Lax;生產環境正確設定 domain 與 secure。
預設靠 Cookie,若關閉 Cookie 需透過 URL 傳遞:
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 0); // 允許 URL 傳遞
ini_set('session.use_trans_sid', 1); // 自動附加 SID 到連結
但 不建議 啟用 URL 傳遞(安全風險),應修正 Cookie 問題。
; php.ini
session.gc_probability = 1
session.gc_divisor = 1000 ; 0.1% 機率觸發 GC
session.gc_maxlifetime = 1440 ; 24 分鐘過期
若流量大、GC 頻率高,可能誤刪有效 Session。建議:
gc_divisor(如 10000)phpinfo() 確認 session.save_path 可寫var_dump(session_id()) 檢查 ID 是否固定var_dump($_COOKIE) 確認 PHPSESSID 正常送出ls -la /path/to/sessions/ 觀察 sess_* 檔案建立/更新時間session.save_handler = files 排除自定義 Handler 問題; php.ini 或執行時設定
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=yourpass&database=1"
; 自動處理鎖、過期、叢集,效能與穩定度遠優於檔案
系統性排查上述五大方向,99% 的 Session 失效問題皆可解決。