Session(階段作業)是伺服器端儲存使用者狀態資料的機制。當訪客進入網站時建立 Session,離開或逾時則銷毀。與 Cookie 儲存於瀏覽器不同,Session 資料儲存在伺服器(預設為檔案,可擴展為資料庫、Redis、Memcached),僅透過 Session ID(通常存於 Cookie)識別使用者。
session_start() 啟動或恢復 SessionPHPSESSID)或 URL 參數取得 Session ID$_SESSION 超全域陣列載入記憶體<?php
// 必須在輸出任何內容前呼叫
session_start();
// 註冊變數(PHP 4 風格,已棄用)
// session_register("username");
// 現代寫法:直接操作 $_SESSION 陣列
$_SESSION['username'] = 'john_doe';
$_SESSION['login_time'] = time();
$_SESSION['permissions'] = ['read', 'write'];
// 讀取
echo $_SESSION['username'];
// 刪除單一變數
unset($_SESSION['permissions']);
// 銷毀整個 Session
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"]
);
}
?>
| 參數 | 預設值 | 建議值 | 說明 |
|---|---|---|---|
| session.save_handler | files | redis/memcached | 儲存介質,分散式系統必改 |
| session.save_path | /tmp | /var/lib/php/sessions | 檔案儲存路徑,需權限 600 |
| session.gc_maxlifetime | 1440 | 1800~7200 | 垃圾回收最大壽命(秒) |
| session.cookie_httponly | Off | On | 防止 JavaScript 存取 Cookie(防 XSS) |
| session.cookie_secure | Off | On (HTTPS) | 僅 HTTPS 傳輸 Cookie |
| session.use_strict_mode | Off | On | 拒絕未初始化的 Session ID |
| session.sid_length | 32 | 48 | Session ID 長度,越長越安全 |
| 特性 | Session | Cookie |
|---|---|---|
| 儲存位置 | 伺服器端 | 客戶端瀏覽器 |
| 資料大小限制 | 受限於伺服器記憶體/硬碟 | 約 4KB |
| 安全性 | 較高(資料不外露) | 較低(可被竄改、側錄) |
| 跨網域共享 | 需共享儲存介質 | 可設定 domain 共享 |
| 適用場景 | 敏感資料、大量資料、購物車 | 偏好設定、追蹤、Remember Me |
<?php
session_start();
function addToCart($productId, $quantity = 1) {
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
if (isset($_SESSION['cart'][$productId])) {
$_SESSION['cart'][$productId] += $quantity;
} else {
$_SESSION['cart'][$productId] = $quantity;
}
}
function getCartTotal() {
$total = 0;
if (!empty($_SESSION['cart'])) {
// 假設從資料庫取得價格
foreach ($_SESSION['cart'] as $pid => $qty) {
$price = getProductPrice($pid); // 自訂函式
$total += $price * $qty;
}
}
return $total;
}
// 使用範例
addToCart(101, 2);
addToCart(105, 1);
echo "購物車總金額:$" . getCartTotal();
?>
<?php
class DatabaseSessionHandler implements SessionHandlerInterface {
private $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function open($savePath, $sessionName) { return true; }
public function close() { return true; }
public function read($sessionId) {
$stmt = $this->pdo->prepare("SELECT data FROM sessions WHERE id = ? AND expiry > ?");
$stmt->execute([$sessionId, time()]);
return $stmt->fetchColumn() ?: '';
}
public function write($sessionId, $data) {
$expiry = time() + ini_get('session.gc_maxlifetime');
$stmt = $this->pdo->prepare("INSERT INTO sessions (id, data, expiry) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE data = ?, expiry = ?");
return $stmt->execute([$sessionId, $data, $expiry, $data, $expiry]);
}
public function destroy($sessionId) {
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE id = ?");
return $stmt->execute([$sessionId]);
}
public function gc($maxLifetime) {
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE expiry < ?");
return $stmt->execute([time()]);
}
}
// 註冊自訂處理器
$handler = new DatabaseSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();
?>
session.use_strict_mode = Onsession_regenerate_id(true)session_write_close() 提早釋放鎖定Session 是 PHP 開發維持狀態的核心機制。正確理解其運作原理、配置安全參數、選擇適合架構的儲存介質,能構建安全、高效能的 Web 應用程式。現代開發建議搭配框架(Laravel、Symfony)內建的 Session 管理元件,享受更完善的封裝與安全防護。