session_start():讀取 Cookie PHPSESSID,或產生新 ID$_SESSION$_SESSION 寫回儲存介質| 處理器 | 設定 | 優點 | 缺點 |
|---|---|---|---|
| files (預設) | session.save_handler=files | 零設定、預設啟用 | 單機、大量檔案效能差、難水平擴展 |
| Redis | session.save_handler=redis session.save_path="tcp://127.0.0.1:6379" | 高效能、原生支援集群、TTL 自動過期 | 需額外元件 |
| Memcached | session.save_handler=memcached session.save_path="127.0.0.1:11211" | 記憶體級速度、分散式 | 資料不可靠(重啟遺失)、無原生 TTL 掃描 |
| Database | 自訂 session_set_save_handler | 持久化、可查詢、ACID | 寫入延遲、需維護 schema |
# php.ini
session.save_handler = redis
session.save_path = "tcp://redis-cluster:6379?auth=password&database=0&prefix=PHPSESS:"
session.gc_maxlifetime = 1440
class DbSessionHandler implements SessionHandlerInterface {
private PDO $pdo;
public function __construct(PDO $pdo) { $this->pdo = $pdo; }
public function open($path, $name): bool { return true; }
public function close(): bool { return true; }
public function read($id): string|false {
$stmt = $this->pdo->prepare('SELECT data FROM sessions WHERE id = ? AND expiry > ?');
$stmt->execute([$id, time()]);
return $stmt->fetchColumn() ?: '';
}
public function write($id, $data): bool {
$expiry = time() + ini_get('session.gc_maxlifetime');
$stmt = $this->pdo->prepare('INSERT INTO sessions (id, data, expiry) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE data=VALUES(data), expiry=VALUES(expiry)');
return $stmt->execute([$id, $data, $expiry]);
}
public function destroy($id): bool {
$stmt = $this->pdo->prepare('DELETE FROM sessions WHERE id = ?');
return $stmt->execute([$id]);
}
public function gc($maxlifetime): int|false {
$stmt = $this->pdo->prepare('DELETE FROM sessions WHERE expiry < ?');
$stmt->execute([time()]);
return $stmt->rowCount();
}
}
// 註冊
$handler = new DbSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();
<?php
// 必須在 session_start() 之前設定
ini_set('session.cookie_httponly', '1'); // 防 XSS 竊取
ini_set('session.cookie_secure', '1'); // 僅 HTTPS 傳送
ini_set('session.cookie_samesite', 'Lax'); // CSRF 防護
ini_set('session.use_strict_mode', '1'); // 拒絕未初始化的 Session ID
ini_set('session.sid_length', '48'); // ID 長度(PHP 7.1+)
ini_set('session.sid_bits_per_character', '6'); // 熵值
ini_set('session.gc_probability', '1');
ini_set('session.gc_divisor', '1000'); // 0.1% 機率觸發 GC
ini_set('session.gc_maxlifetime', '1440'); // 24 分鐘
session_start();
<?php
session_start();
// 登入成功後,重新產生 ID
if ($loginSuccess) {
session_regenerate_id(true); // true = 刪除舊 session 檔案
$_SESSION['user_id'] = $userId;
}
| 函式 | 用途 |
|---|---|
| session_start() | 啟動/恢復 Session |
| session_id() | 取得/設定當前 ID |
| session_name() | 取得/設定 Cookie 名稱(預設 PHPSESSID) |
| session_regenerate_id() | 產生新 ID,可選刪除舊資料 |
| session_destroy() | 銷毀伺服器端資料(不刪除 Cookie) |
| session_unset() | 清空 $_SESSION 陣列 |
| session_write_close() | 提前寫入並關閉,釋放鎖定 |
| session_set_save_handler() | 註冊自訂儲存介面 |
原始來源:www.111cn.net