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

PHP Session 完整指南:啟動、變數註冊、常見陷阱與安全設定

     編輯:PHP 相關知識

核心函式速查

函式用途備註
session_start()啟動或恢復 Session必須在**任何輸出前**呼叫
session_destroy()銷毀伺服器端 Session 資料不會刪除瀏覽器 Cookie
session_unset()釋放所有 `$_SESSION` 變數配合 destroy 使用
session_regenerate_id()產生新 Session ID登入後必呼叫,防 Session Fixation
session_set_cookie_params()設定 Cookie 參數 (lifetime, path, domain, secure, httponly)需在 session_start() 前呼叫

基本操作範例

<?php
// 1. 啟動 (建議放在統一入口檔)
session_start();

// 2. 寫入變數 (PHP 5.4+ 直接用 $_SESSION)
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'admin';
$_SESSION['permissions'] = ['read', 'write'];

// 3. 讀取
if (isset($_SESSION['user_id'])) {
    echo "歡迎,{$_SESSION['username']}";
}

// 4. 刪除單一變數
unset($_SESSION['temp_data']);

// 5. 登出:完整清除
$_SESSION = [];
if (ini_get('session.use_cookies')) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params['path'], $params['domain'],
        $params['secure'], $params['httponly']
    );
}
session_destroy();

常見陷阱與解決

1. "Headers already sent" 錯誤

原因:session_start() 前有空白、BOM、echo、HTML 標籤。

解決:確保 session_start() 在檔案最頂端,檔案存為 **UTF-8 無 BOM**。

2. 變數跨頁面消失

檢查清單:

  • 每個頁面都有 session_start()?
  • session.cookie_lifetime 是否為 0 (瀏覽器關閉即失效)?
  • 子域名共享需設定 session.cookie_domain = ".example.com"。
  • 安全模式下 session.use_trans_sid 可能導致 URL 附帶 SID。

3. 物件無法序列化

限制:resource (資料庫連線、檔案控制代碼)、Closure、循環引用物件無法存入 Session。

對策:只存純資料陣列/標量;物件實作 __sleep/__wakeup 控制序列化行為。

安全加固設定 (php.ini 或啟動腳本)

; 只透過 Cookie 傳遞 SID,不走 URL
session.use_only_cookies = 1
session.use_trans_sid = 0

; Cookie 設定
session.cookie_httponly = 1      ; 防 XSS 竊取
session.cookie_secure = 1        ; 僅 HTTPS 傳送 (正式環境必開)
session.cookie_samesite = "Lax"  ; CSRF 保護

; Session ID 長度與熵值
session.sid_length = 32
session.sid_bits_per_character = 5

; 垃圾回收機率 (1/1000)
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440    ; 24 分鐘無活動視為過期

分散式 Session (多伺服器)

預設 files handler 僅限單機。叢集環境請改用:

  • Redis:session.save_handler = redis、session.save_path = "tcp://127.0.0.1:6379" (需 phpredis 擴充)。
  • Memcached:類似設定。
  • 資料庫:自訂 session_set_save_handler() 實作介面。

自動啟動權衡

session.auto_start = 1 可省去手動呼叫,但:

  • 無法在 Session 中存放物件 (類別定義必須在 auto_start 前載入,實務上難保證)。
  • 所有頁面都會啟動 Session,增加無謂 I/O。
  • 建議:關閉自動啟動,在需要的入口統一 session_start()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved