Session 將用戶數據存儲在伺服器端(文件/Redis/資料庫),僅在客戶端 Cookie 中保存一個 session_id(預設名 PHPSESSID)。請求時瀏覽器自動攜帶該 ID,PHP 自動載入對應數據到 $_SESSION 超全局陣列。
<?php
// 必須在任何輸出前調用
session_start();
// 可選:自定義存儲處理器(Redis、DB 等)
// ini_set('session.save_handler', 'redis');
// ini_set('session.save_path', 'tcp://127.0.0.1:6379');
?>
<?php
$_SESSION['login_user'] = 'zs'; // 字符串
$_SESSION['user_id'] = 1001; // 整數
$_SESSION['is_admin'] = true; // 布爾
$_SESSION['permissions'] = ['read', 'write']; // 陣列
$_SESSION['cart'] = new Cart(); // 物件(需實現 __sleep/__wakeup 或 Serializable)
?>
<?php
// 讀取單值
$user = $_SESSION['login_user'] ?? '游客';
// 判斷是否登入
if (empty($_SESSION['user_id'])) {
header('Location: /login.php');
exit;
}
// 遍歷所有會話數據
foreach ($_SESSION as $key => $val) {
echo "$key => ";
var_dump($val);
}
?>
<?php
// 刪除單個鍵
unset($_SESSION['login_user']);
// 刪除全部會話數據(但保留 session_id)
$_SESSION = [];
// 徹底銷毀會話:刪除伺服器存儲 + 客戶端 Cookie
session_destroy(); // 僅刪除伺服器端文件
// 同時刪除客戶端 Cookie
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']
);
}
?>
<?php
$sid = session_id(); // 當前會話 ID
$sid = session_name(); // Cookie 名稱(預設 PHPSESSID)
$sid = SID; // 常量:若未啟用 Cookie 則為 "PHPSESSID=abc123",否為空字符串
?>
| 配置項 | 推薦值 | 說明 |
|---|---|---|
session.cookie_httponly | 1 | 防 XSS 竊取 Session ID |
session.cookie_secure | 1 | 僅 HTTPS 傳輸(生產必開) |
session.cookie_samesite | 'Lax' | CSRF 防護 |
session.use_strict_mode | 1 | 拒絕未初始化的 ID,防固定攻擊 |
session.gc_maxlifetime | 1440 (24h: 86400) | 伺服器端數據最大存活秒數 |
session.save_path | /var/lib/php/sessions | 權限 700,屬於 php-fpm 用戶 |
可在 php.ini 或運行時 ini_set() 設置;session_set_cookie_params() 需在 session_start() 前調用。
session.save_handler=redis,高性能、支援集群、可設 TTL 自動過期。SessionHandlerInterface 寫入 MySQL/PostgreSQL,便於審計。session_start() 是否漏寫;確認 session.save_path 可寫;排查多伺服器未共享存儲;注意 session_write_close() 過早調用。session_start() 必須在任何 echo、HTML、空白行、BOM 前調用。session_write_close() 釋放鎖,或改用 Redis 非阻塞鎖。