一、Session 生成機制
HTTP 無狀態,Session 透過伺服器端儲存狀態,客戶端以 Cookie 傳遞 Session ID 來識別用戶。
流程圖解
- 呼叫
session_start()
- PHP 產生唯一 Session ID(如
2bd170b3f86523f1b1b60b55ffde0f66)
- 伺服器
session.save_path(預設 /tmp)建立檔案 sess_{SESSION_ID}
- 客戶端 Cookie 建立
PHPSESSID={SESSION_ID}
- 後續請求瀏覽器自動攜帶 Cookie,PHP 讀取 ID 找到對應檔案,載入
$_SESSION
檔案內容格式
name|s:11:"wanchun0222";blog|s:13:"coderbolg.com";
格式:變數名|型別:長度:"值",以分號分隔。
二、Session 過期與垃圾回收(GC)
伺服器端:session.gc_maxlifetime
預設 1440 秒(24 分鐘)。檔案最後修改時間超過此值視為過期。
GC 觸發機率:session.gc_probability / session.gc_divisor
預設 1/100,即每 100 次請求觸發 1 次掃描,刪除過期檔案。
客戶端:session.cookie_lifetime
預設 0(瀏覽器關閉即失效)。若設為 3600,Cookie 存活 1 小時。建議與 gc_maxlifetime 設定一致。
三、客戶端儲存機制:Cookie 被禁用怎麼辦?
PHP 支援兩種傳遞 Session ID 方式:
| 方式 | 設定 | 優點 | 缺點 |
| Cookie(預設) | session.use_cookies=1 | 自動、安全 | 用戶可禁用 |
| URL 重寫(GET) | session.use_trans_sid=1 | 無需 Cookie | URL 暴露 SID、安全性低、不適用 POST |
最佳實踐:優先使用 Cookie;若必須支援無 Cookie 環境,啟用 use_trans_sid 並搭配 session.use_only_cookies=0,但需評估安全風險(Session Fixation、Referer 洩漏)。
四、進階設定與安全建議
- session.save_handler:預設 files,生產環境建議改用 Redis/Memcached(分散式、效能佳)。
- session.name:自訂 Cookie 名稱(預設 PHPSESSID),避免與其他應用衝突。
- session.cookie_httponly=1:防止 JS 竊取 Cookie(XSS 防護)。
- session.cookie_secure=1:僅 HTTPS 傳輸 Cookie。
- session.use_strict_mode=1:拒絕未初始化的 Session ID,防 Session Fixation。
- session.regenerate_id(true):登入成功、權限變更時重新生成 ID,銷毀舊 Session。
五、常見問題排查
- Session 不生效:檢查
session_start() 是否在輸出前呼叫、Cookie 是否被瀏覽器阻擋、session.save_path 是否可寫。
- Session 資料遺失:GC 過於激進、多伺服器未共享儲存、
session.cookie_domain 設定錯誤。
- 並發阻塞:預設檔案鎖機制導致同一 Session 並發請求排隊。改用 Redis +
session.lock 策略或非阻塞寫入。
結語
Session 看似簡單,背後涉及 ID 生成、儲存引擎、GC 機制、客戶端協商、安全防護等多層面。理解核心原理,才能在分散式架構、高併發、安全合規等場景下做出正確架構決策。
- 上一篇文章: 深入 PHP 5 物件複製機制:從淺複製到深複製的完整解析
- 下一篇文章: PHP 從大型文字檔隨機抽取指定行數的高效寫法
Copyright ©
程式碼之家 All Rights Reserved