| 函式 | 用途 | 備註 |
|---|---|---|
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();
原因:session_start() 前有空白、BOM、echo、HTML 標籤。
解決:確保 session_start() 在檔案最頂端,檔案存為 **UTF-8 無 BOM**。
檢查清單:
session_start()?session.cookie_lifetime 是否為 0 (瀏覽器關閉即失效)?session.cookie_domain = ".example.com"。session.use_trans_sid 可能導致 URL 附帶 SID。限制:resource (資料庫連線、檔案控制代碼)、Closure、循環引用物件無法存入 Session。
對策:只存純資料陣列/標量;物件實作 __sleep/__wakeup 控制序列化行為。
; 只透過 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 分鐘無活動視為過期
預設 files handler 僅限單機。叢集環境請改用:
session.save_handler = redis、session.save_path = "tcp://127.0.0.1:6379" (需 phpredis 擴充)。session_set_save_handler() 實作介面。session.auto_start = 1 可省去手動呼叫,但:
session_start()。