在 PHP 開發中,雖然 setcookie() 是最常用的設定 Cookie 函式,但有時候我們需要更底層的控制,或是需要在特定情境下手動組裝 HTTP 標頭。此時透過 header() 函式直接發送 Set-Cookie 標頭便是一個實用的替代方案。
以下是一個標準的範例程式碼:
<?php
header("Set-Cookie: testcookie=中文; path=/; domain=.phpv.net; expires=" . gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT", time() + 9600));
?>
關鍵參數說明:
urlencode() 編碼以確保相容性)。gmstrftime() 產生符合 RFC 1123 標準的時間字串,time() + 9600 表示 2.67 小時後過期。header() 必須在任何 HTML 輸出、echo、空白字元之前執行,否則會觸發 Headers already sent 警告導致 Cookie 設定失敗。
雖然現代瀏覽器大多支援 UTF-8 的 Cookie 值,但為了最大相容性,建議寫入時使用 urlencode(),讀取時用 urldecode() 還原:
<?php
$value = urlencode('中文內容');
header("Set-Cookie: mycookie={$value}; path=/; domain=.example.com; expires=" . gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT", time() + 3600));
?>
現代 Web 應用建議加入以下屬性提升安全性:
Secure:僅在 HTTPS 連線下傳送。HttpOnly:防止 JavaScript 存取,降低 XSS 風險。SameSite=Lax 或 Strict:防禦 CSRF 攻擊。header("Set-Cookie: testcookie=value; path=/; domain=.example.com; Secure; HttpOnly; SameSite=Lax");
| 問題 | 可能原因 | 解決方案 |
|---|---|---|
| Cookie 未生效 | 域名設定錯誤(如 localhost 無法設定 domain) | 本機測試時移除 domain 參數,或修改 hosts 檔案使用真實域名 |
| 中文顯示亂碼 | 編碼不一致 | 統一使用 urlencode()/urldecode(),確認檔案儲存為 UTF-8 無 BOM |
| 過期時間不準 | 伺服器時間與客戶端時區差異 | 統一使用 GMT 時間,避免依賴本地時區 |
雖然 setcookie() 封裝良好且易用,但掌握 header() 手動發送 Cookie 的技巧,能在需要精確控制標頭、避開框架限制、或是除錯網路請求時提供更大的彈性。記住核心原則:正確的參數格式、輸出前發送、妥善處理編碼與安全屬性。