Heim >php教程 >php手册 >php不同子域的同名cookie问题解决方法

php不同子域的同名cookie问题解决方法

WBOY
WBOYOriginal
2016-06-13 09:46:381164Durchsuche

$_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是非常不明智的

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn