首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP Session 失效排查實戰:從權限、配置到程式碼邏輯

     編輯:PHP 相關知識

Session 只在當前請求有效,下一次請求變空陣列,是典型的 Session 持久化失效。本文記錄一次真實排查過程,涵蓋權限、配置、程式碼三大維度,並給出通用排查清單。

現象

  • `$_SESSION` 寫入後當前請求可讀。
  • 下一請求 `$_SESSION === []`,彷彿執行過 `session_destroy()`。
  • Cookie 正常存在(`PHPSESSID`),瀏覽器未禁用 Cookie。

排查路徑與結論

  1. session_start():每個請求都有調用,排除。
  2. session.gc_maxlifetime:代碼中動態設定 `ini_set('session.gc_maxlifetime', $lefttime)`,數值正常,排除。
  3. Cookie 禁用:檢查瀏覽器 Cookie 儲存正常,`$_COOKIE['PHPSESSID']` 存在,排除。
  4. 框架問題:ThinkPHP/SpeedPHP 等框架無類似報告,排除。
  5. 關鍵突破:Session 儲存目錄權限:
    # 檢查 php.ini
    session.save_path = "/var/lib/php/session"
    
    # 進入目錄檢查權限
    ls -ld /var/lib/php/session
    # 輸出:drwxrwx--- 2 root apache 4096 ...  <-- 其他用戶無讀寫權限!

    Web 進程使用者(如 www-data/apache/nginx)無法寫入 Session 檔案,導致每次請求都建立新 Session 但無法持久化。

解決方案

# 方案 1:修改目錄擁有者(推薦)
chown -R www-data:www-data /var/lib/php/session
chmod 770 /var/lib/php/session

# 方案 2:修改權限(不推薦生產環境)
chmod 777 /var/lib/php/session

# 方案 3:自定義儲存路徑至專案可寫目錄
# php.ini 或程式碼中:
ini_set('session.save_path', __DIR__ . '/../storage/sessions');
# 確保該目錄存在且 Web 使用者可寫

通用排查清單(下次直奔主題)

順序檢查項目指令/代碼
1session.save_path 路徑是否存在php -i | grep session.save_path
2該目錄 Web 使用者是否可讀寫ls -ld /path/to/session; sudo -u www-data touch /path/to/session/test
3磁碟空間是否滿df -h /path/to/session
4inode 是否耗盡df -i /path/to/session
5session.gc_probability/divisor 導致過度 GCphp -i | grep 'session.gc'
6多專案共用 save_path 造成衝突各專案設定獨立 save_path
7程式碼中是否有 session_destroy()/unset($_SESSION)grep -r "session_destroy" .
8session.name 是否統一(跨子域)ini_set('session.name', 'MYAPP')
9Cookie 域/路徑/安全標誌設定session_set_cookie_params()
10使用 Redis/Memcached 存儲 Sessionphp.ini: session.save_handler=redis

生產環境建議:改用 Redis 存儲 Session

# 安裝 php-redis 擴展
# php.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=yourpass&database=1"
# 或多節點高可用
session.save_path = "tcp://redis1:6379?weight=1, tcp://redis2:6379?weight=1"
優點:跨伺服器共享、效能高、支援集群、可設定 TTL、避免檔案系統權限/Inode 問題。
核心教訓:Session 失效 90% 是儲存層權限或路徑問題。遇到「只在當前請求有效」,第一時間檢查 session.save_path 目錄權限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved