| 特性 | Cookie | Session |
|---|---|---|
| 儲存位置 | 客戶端瀏覽器 | 伺服器端(檔案、Redis、DB) |
| 容量限制 | 約 4 KB / 個 | 受伺服器儲存空間限制,通常無上限 |
| 生命週期 | 可設定過期時間,持久化 | 預設瀏覽器關閉即失效,可透過 `session.gc_maxlifetime` 調整 |
| 安全性 | 可被竄改、攔截,需加密簽名 | 資料不直接暴露給客戶端,較安全 |
| 跨域行為 | 受同源策略限制 | 伺服器端共享儲存可跨子域(設定 `session.cookie_domain`) |
<?php
// 寫入:名稱、值、過期時間、路徑、域名、Secure、HttpOnly
setcookie('user_pref', 'dark_mode', [
'expires' => time() + 86400 * 30, // 30 天
'path' => '/',
'domain' => '.example.com', // 共享給子域
'secure' => true, // 僅 HTTPS 傳輸
'httponly' => true, // JS 無法讀取,防 XSS
'samesite' => 'Lax', // CSRF 保護
]);
// 讀取
$theme = $_COOKIE['user_pref'] ?? 'light';
// 刪除:設定過期時間為過去
setcookie('user_pref', '', ['expires' => time() - 3600, 'path' => '/']);
<?php
// 1. 必須在輸出前啟動
session_start([
'cookie_lifetime' => 86400, // Cookie 存活 1 天
'gc_maxlifetime' => 86400, // 伺服器端資料最長 1 天
'use_strict_mode' => true, // 防止 Session Fixation
'cookie_httponly' => true,
'cookie_secure' => true, // 僅 HTTPS
'cookie_samesite' => 'Lax',
]);
// 2. 寫入
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'alice';
$_SESSION['roles'] = ['member', 'editor'];
// 3. 讀取
$userId = $_SESSION['user_id'] ?? null;
// 4. 刪除單一鍵
unset($_SESSION['username']);
// 5. 銷毀整個 Session(登出)
session_unset(); // 清空 $_SESSION 陣列
session_destroy(); // 刪除伺服器端儲存檔案
// 並發送新的 Session ID Cookie 覆蓋舊的
setcookie(session_name(), '', time() - 3600, '/');
預設將 Session 存為檔案(`session.save_handler = files`),高併發或分散式架構下建議改用 Redis 或 資料庫。參考 文章 152522 完整實作範例。
原文摘自 matter605924657