网站地图    收藏   

主页 > php专栏 > php会话 >

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

来源:自学PHP网    时间:2014-11-27 20:45 作者: 阅读:

[导读] $_COOKIE是php中一个非常好用的东西,但是有时我们会碰到同域名下的不同子域名一样,这样就会存在只能保留一个cookie的问题。...

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

$_COOKIE是php中一个非常好用的东西,但是有时我们会碰到同域名下的不同子域名一样,这样就会存在只能保留一个cookie的问题。

PHP的超全局变量$_COOKIE带来了很多便利,在某些情况下也会造成困惑。比如在根域和子域下存在同名cookie,$_COOKIE中只能保存一个,应该是哪个?

RFC建议使用长度最长的那个,这样精度最高,但是不同浏览器处理方式不同。我只测试了Chrome,Chrome中根域和子域的同名cookie都发送出去了,这样PHP只接收排在前面的同名cookie,后面的被忽略,这样很容易接收到错误的值。据说Safari遵循了RFC的建议,没有亲自测试,其他浏览器也没有测试。

首先通过SwitchHosts设定虚拟域名:www.phpfensi.com,并且配置好Web服务器,当然,你手动设置Hosts文件也可以,我本意是为了多介绍几个工具,然后编写设置Cookie的PHP脚本,先设置子域,再设置根域,代码如下:

  1. <?php 
  2. setcookie("bar""www", time() + 10, "/""www.phpfensi.com");  
  3. setcookie("bar""foo", time() + 10, "/"".phpfensi.com"); 
  4. ?> 

再编写浏览Cookie的脚本,代码如下:

  1. <?php 
  2. var_dump($_COOKIE); 
  3. ?> 

BTW:最初写脚本的时候我竟然在setcookie前使用了var_dump,也就是在发送请求头之前有了输出,犯了这样的初学者错误实在是罪过,可更令人惊讶的是脚本没有报错,查了半天原来是因为php.ini里缺省output_buffering = 4096。

先设置再浏览,就能看到结果了,结果显示有效的是子域下的Cookie,重开一个浏览器窗口,并使用WebDeveloper删除Cookie,或手动删除,避免对结果造成影响,然后调换两次调用setcookie的顺序,也就是先设置根域,再设置子域,代码如下:

  1. <?php 
  2. setcookie("bar""foo", time() + 10, "/"".phpfensi.com");  
  3. setcookie("bar""www", time() + 10, "/""www.phpfensi.com"); 
  4. ?> 

先设置再浏览,就能看到结果了,结果显示有效的是根域下的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是非常不明智的

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论