除了這樣寫
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>
你還可以這樣寫
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
除了這樣寫
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>
你還可以這樣寫
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
想要移除 cookie 嗎?
很多人用複雜的方式
setcookie('name', 'content', time()-3600);
但為什麼要讓它這麼複雜,並冒著客戶端時間錯誤導致失效的風險呢?為什麼要繞著 time(); 打轉?
這是取消設定 cookie 最簡單的方法
setcookie('name', 'content', 1);
就這樣。
只是一個例子來闡明陣列選項的用法,尤其因為 Mozilla 將棄用/懲罰使用 SameSite = none,如果沒有使用陣列選項,則預設使用此選項。
<?php
$arr_cookie_options = array (
'expires' => time() + 60*60*24*30,
'path' => '/',
'domain' => '.example.com', // 為了相容性,前面加上點,或是使用子網域
'secure' => true, // 或 false
'httponly' => true, // 或 false
'samesite' => 'None' // None || Lax || Strict
);
setcookie('TestCookie', 'The Cookie Value', $arr_cookie_options);
?>
在任何網頁瀏覽器中,都有一個非常常用的選項「開啟之前的視窗和分頁」,預設情況下是停用的,但許多人會啟用它。
當此選項處於啟用狀態時,網頁瀏覽器在關閉並重新開啟時,並不會執行終止並啟動新工作階段的動作,而是會儲存並還原目前的階段,連同工作階段 Cookie 和 sessionStorage。
與預期相反,工作階段 Cookie 和 sessionStorage 都可以存活很長時間,直到使用者在關閉網頁瀏覽器之前關閉分頁為止。
如果您希望 Cookie(例如具有時間偏移的 Cookie)保證具有較短的存活期,則應明確指定此較短的存活期,而不是依賴工作階段 Cookie 的自動刪除功能。
請注意,設定「陣列 Cookie」時,會為陣列的每個元素設定一個單獨的 Cookie。
在高流量的網站上,這會大幅增加客戶端後續 HTTP 請求的大小(包括對同一個網域上的靜態內容的請求)。
更重要的是,Cookie 規範規定瀏覽器每個網域只需接受 20 個 Cookie。Firefox 將此限制增加到 50 個,Opera 增加到 30 個,但 IE6 和 IE7 則強制執行每個網域 20 個 Cookie 的限制。超出此限制的任何 Cookie 都會取代較舊的 Cookie,或被瀏覽器忽略/拒絕。
值得一提的是:您應該避免在 Cookie 名稱中使用點號。
<?php
// 這實際上會設定 'ace_fontSize' 名稱:
setcookie( 'ace.fontSize', 18 );
?>
這裡沒有清楚說明的一點,讓我完全困惑了一陣子,那就是網域名稱必須至少包含兩個點號 (.),因此 'localhost' 是無效的,瀏覽器會拒絕設定 Cookie!對於 localhost,您應該使用 false。
要讓你的程式碼在本地端和正式網域都能運作,你可以這樣做:
<?php
$domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('cookiename', 'data', time()+60*60*24*365, '/', $domain, false);
?>
如果你想刪除網域上的所有 Cookie,你可能會想使用以下的值:
<?php $_SERVER['HTTP_COOKIE'] ?>
而不是
<?php $_COOKIE ?>
來判斷 Cookie 名稱。
如果 Cookie 名稱是陣列表示法,例如:user[username]
那麼 PHP 會在 $_COOKIE 中自動建立一個對應的陣列。請改用 $_SERVER['HTTP_COOKIE'],因為它反映了實際的 HTTP 請求標頭。
<?php
// 刪除 cookies
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookies = explode(';', $_SERVER['HTTP_COOKIE']);
foreach($cookies as $cookie) {
$parts = explode('=', $cookie);
$name = trim($parts[0]);
setcookie($name, '', time()-1000);
setcookie($name, '', time()-1000, '/');
}
}
?>
注意事項:如果你使用 URL 重寫規則來將 domain.com/bla/stuf/etc 之類的東西轉換成參數,那麼在設定 Cookie 時可能會遇到問題。
至少在我的設定中,其中一個參數的更改導致 Cookie 不再「存在」。
解決方法很簡單:指定網域。'/' 通常就可以了。
「PHPSESSID」Cookie 即將被拒絕,因為它的「sameSite」屬性設為「none」或無效值,且沒有「secure」屬性。要了解更多關於「sameSite」屬性的資訊,請造訪 https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite.
<?php
ini_set("session.cookie_secure", 1);
session_start();
我的 PHP 程式碼 ....
?>
請注意,$_COOKIE 變數不會儲存多個同名的 Cookie。在相同主機但不同子網域的情況下,設定兩個同名的 Cookie 是合法的。
<?php
setcookie("testcookie", "value1hostonly", time(), "/", ".example.com", 0, true);
setcookie("testcookie", "value2subdom", time(), "/", "subdom.example.com", 0, true);
?>
瀏覽器發出的下一個請求會在 $_SERVER['HTTP_COOKIE'] 變數中包含這兩個 Cookie,但在 $_COOKIE 變數中只會找到其中一個。對 subdom.example.com 的請求會包含兩個 Cookie,而對 example.com 或 www.example.com 的瀏覽器請求只會發送值為「value1hostonly」的 Cookie。
<?php
$kaker = explode(";", $_SERVER['HTTP_COOKIE']);
foreach($kaker as $val){
$k = explode("=", $val);
echo trim($k[0]) . " => " . $k[1];
}
// 輸出
testcookie => value1hostonly
testcookie => value2subdom
?>
Cookie 名稱中的句點(例如 user.name)在 $_COOKIE 陣列中似乎會顯示為底線(例如 user_name)。這表示,例如,必須使用 $_COOKIE["user_name"] 來讀取使用 setcookie("user.name" ...) 設定的 Cookie,這已經相當令人困惑了。
此外,變數 $_COOKIE["user_name"] 會保留 setcookie("user.name" ...) 設定的值,而且無論呼叫 setcookie("user_name" ...) 多少次,都無法更改此值。這個問題可以透過清除「user.name」Cookie 來輕鬆解決,但由於 $_COOKIE 中只有「user_name」,因此可能需要一些時間才能意識到這一點。
希望這可以節省大家一些時間。