Cookie 屬於 HTTP 回應標頭(Set-Cookie),必須在任何 HTML/空白輸出之前呼叫 setcookie()。瀏覽器收到後儲存,後續請求自動攜帶 Cookie 標頭送回伺服器。
setcookie(
string $name,
string $value = '',
int $expire = 0,
string $path = '',
string $domain = '',
bool $secure = false,
bool $httponly = false
): bool
| 參數 | 說明 | 預設/備註 |
|---|---|---|
| name | Cookie 名稱(必填) | — |
| value | 值,自動 urlencode | 空字串 = 刪除 |
| expire | Unix 時間戳(秒),time()+3600 為 1 小時後過期 | 0 = 瀏覽器關閉即失效(Session Cookie) |
| path | 生效路徑 | 預設為當前腳本目錄,/ 代表全站 |
| domain | 生效域名 | .example.com 含子域名,www.example.com 僅特定主機 |
| secure | 僅 HTTPS 傳輸 | 生產環境建議 true |
| httponly | 禁止 JavaScript 存取($_COOKIE 仍可讀) | 防 XSS,建議 true |
<?php
// 1. 簡單 Session Cookie(瀏覽器關閉失效)
setcookie('lang', 'zh-TW');
// 2. 指定過期時間:1 小時
setcookie('token', 'abc123', time() + 3600);
// 3. 完整參數:跨目錄、跨子域名、僅 HTTPS、HttpOnly
setcookie(
'user_pref',
json_encode(['theme' => 'dark', 'font' => 14]),
time() + 86400 * 30, // 30 天
'/', // 全站路徑
'.example.com', // 含所有子域名
true, // Secure
true // HttpOnly
);
// 4. 陣列形式(自動建立多個同名 Cookie)
setcookie('fruits[]', 'apple');
setcookie('fruits[]', 'banana');
// 或指定索引
setcookie('colors[0]', 'red');
setcookie('colors[1]', 'blue');
?>
PHP 內部處理 Cookie 陣列為後進先出(LIFO)。若需先刪除舊值再設定新值,必須先寫入新值程式碼,再寫入刪除程式碼,否則新值會被覆蓋。
<?php
// 1. 超全域陣列 $_COOKIE(自動 urlencode 解碼)
echo $_COOKIE['lang']; // 'zh-TW'
echo $_COOKIE['fruits'][0]; // 'apple'
echo count($_COOKIE['fruits']); // 2
// 2. 相容舊版:$HTTP_COOKIE_VARS(PHP 5.4+ 已移除,不建議使用)
// echo $HTTP_COOKIE_VARS['lang'];
?>
注意:當前請求 setcookie() 設定的值 不會立即出現在 $_COOKIE 中,需下一次請求才可讀取。
<?php
// 方式 1:僅傳 name,值設為空字串
setcookie('token', '');
// 方式 2:設定過期時間為過去
setcookie('token', '', time() - 3600);
// 完整參數刪除(需與設定時 path/domain 一致)
setcookie('user_pref', '', time() - 3600, '/', '.example.com', true, true);
?>
刪除後 當前頁面 $_COOKIE 仍保留值,下一請求才消失。
www.example.com 設定 Cookie,子系統 api.example.com 讀不到。/app1/、/app2/ 互不共享 Cookie。<?php
// 統一設定:path=/ 、domain=.example.com
$cookieParams = [
'path' => '/',
'domain' => '.example.com', // 前綴點號 = 含所有子域名
'secure' => true,
'httponly' => true,
];
setcookie('ssid', $sessionId, time() + 3600, ...$cookieParams);
?>
| 限制項目 | 標準上限 | 應對策略 |
|---|---|---|
| 單一 Cookie 大小 | 4 KB | 僅存識別碼,資料放 Server Session/Redis |
| 單域名 Cookie 數量 | 20~50 個(瀏覽器差異) | 合併為陣列或 JSON 字串 |
| 總 Cookie 數量 | 300+ | 定期清理無效 Cookie |
| 第三方 Cookie | Chrome/Safari/Firefox 預設封鎖 | 改用 SameSite=Lax/None + Secure |
samesite 選項)<?php
setcookie('auth', $token, [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax', // 或 'None'(跨站需求)配合 Secure
]);
?>
PHPSESSID(名稱可在 php.ini session.name 修改)。session.use_cookies=1、session.cookie_lifetime=0(瀏覽器關閉失效)。session.use_trans_sid=1 自動在 URL 附加 SID(需 --enable-trans-sid 編譯支援),但不推薦(安全風險、URL 汙染)。Cookie 是 HTTP 無狀態協議的關鍵狀態載體。掌握 setcookie() 完整參數、輸出前設定、跨域 path/domain 統一、HttpOnly/Secure/SameSite 防護、刪除時序,並理解瀏覽器容量限制,即可構建安全可靠的身份認證、個人化偏好與追蹤機制。