$_COOKIE是php中一個非常好用的東西,但是有時我們會碰到同網域名稱下的不同子網域名稱一樣,這樣就會存在只能保留一個cookie的問題,下面小編來給各位同學介紹一下。
PHP的超全域變數$_COOKIE帶來了很多便利,在某些情況下也會造成困惑。比如在根域和子域下存在同名cookie,$_COOKIE中只能儲存一個,應該是哪個?
RFC建議使用長度最長的那個,這樣精度最高,但是不同瀏覽器處理方式不同。我只測試了Chrome,Chrome中根域和子域的同名cookie都發送出去了,這樣PHP只接收排在前面的同名cookie,後面的被忽略,這樣很容易接收到錯誤的值。據說Safari遵循了RFC的建議,沒有親自測試,其他瀏覽器也沒有測試。
首先通過SwitchHosts設定虛擬網域名稱:www.bKjia.c0m,並且配置好Web伺服器,當然,你手動設定Hosts檔案也可以,我本意是為了多介紹幾個工具。
然後編寫設定Cookie的PHP指令碼,先設定子域,再設定根域:
| 代碼如下 |
複製代碼 |
setcookie("bar", "www", time() + 10, "/", "www.bKjia.c0m"); setcookie("bar", "foo", time() + 10, "/", ".bKjia.c0m"); ?> |
再編寫瀏覽Cookie的指令碼:
| 代碼如下 |
複製代碼 |
var_dump($_COOKIE); ?> |
BTW:最初寫指令碼的時候我竟然在setcookie前使用了var_dump,也就是在發送要求標頭之前有了輸出,犯了這樣的初學者錯誤實在是罪過,可更令人驚訝的是指令碼沒有報錯,查了半天原來是因為php.ini裡預設output_buffering = 4096。
先設定再瀏覽,就能看到結果了,結果顯示有效是子域下的Cookie。
重開一個瀏覽器視窗,並使用WebDeveloper刪除Cookie,或手動刪除,避免對結果造成影響。
然後調換兩次調用setcookie的順序,也就是先設定根域,再設定子域:
| 代碼如下 |
複製代碼 |
setcookie("bar", "foo", time() + 10, "/", ".bKjia.c0m"); setcookie("bar", "www", time() + 10, "/", "www.bKjia.c0m"); ?> |
先設定再瀏覽,就能看到結果了,結果顯示有效是根域下的Cookie。
重複兩次測試過程,並用Firebug記錄下要求標頭的差異:
第一次先設定子域,再設定根域:要求標頭Cookie的值是bar=www;bar=foo,結果有效是bar=www
第二次先設定根域,再設定子域:要求標頭Cookie的值是bar=foo;bar=www,結果有效是bar=foo
也就說,同名Cookie對於服務端PHP來說,在要求標頭Cookie中,哪個在前哪個生效,後面的會被忽略。
如果使用的不是Firefox,那就用不了Firebug,此時可以用PHP代碼來檢測Cookie頭:
| 代碼如下 |
複製代碼 |
if (isset($_SERVER['HTTP_COOKIE'])) var_dump($_SERVER['HTTP_COOKIE']); |
以上的實驗結論是基於Firefox而言的,由於不同的瀏覽器發送Cookie的策略可能有差異,所以在其他瀏覽器上結果可能會有所不同,比如在Safari下就始終是子域有效,其他瀏覽器如Opera,Chrome等未仔細測試。鑒於這個混亂的結論,所以還是不要在子域和根域下使用同名Cookie為好!
結論:目前在根域和子域中使用同名COOKIE是非常不明智的
http://www.bkjia.com/PHPjc/633196.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/633196.htmlTechArticle$_COOKIE是php中一個非常好用的東西,但是有時我們會碰到同網域名稱下的不同子網域名稱一樣,這樣就會存在只能保留一個cookie的問題,下面小編來給...