学习web开发的朋友都知道cookie的路径有时特别烦人,稍不注意就搞晕了,在网上看到一篇讨论PHP cookie路径的文章不错,拿来和大家分享一把

摘要:

  最近研究使用加密cookie给不同系统作同步登陆,其中遇到了一些关于cookie设置和cookie路径的问题,结合查找的资料和经验写一下总结。

PHP setcookie()函数

定义和用法

  setcookie() 函数向客户端发送一个 HTTP cookie。

  cookie 是由服务器发送到浏览器的变量。cookie 通常是服务器嵌入到用户计算机中的小文本文件。每当计算机通过浏览器请求一个页面,就会发送这个 cookie。

  cookie 的名称指定为相同名称的变量。例如,如果被发送的 cookie 名为 "name",会自动创建名为 $user 的变量,包含 cookie 的值。

  必须在任何其他输出发送前对 cookie 进行赋值。

  如果成功,则该函数返回 true,否则返回 false。

语法

setcookie(name,value,expire,path,domain,secure)
参数描述
name必需。规定 cookie 的名称。
value必需。规定 cookie 的值。
expire可选。规定 cookie 的有效期。
path可选。规定 cookie 的服务器路径。
domain可选。规定 cookie 的域名。
secure可选。规定是否通过安全的 HTTPS 连接来传输 cookie。

提示和注释

  1、可以通过 $HTTP_COOKIE_VARS["user"] 或 $_COOKIE["user"] 来访问名为 "user" 的 cookie 的值

  2、在发送 cookie 时,cookie 的值会自动进行 URL 编码。接收时会进行 URL 解码。如果你不需要这样,可以使用 setrawcookie()代替

COOKIE中的路径问题

  setcookie函数的第四个参数为cookie路径,关于路径的设置,本文做了一些尝试,下面是两个测试页(直接用url表示路径和文件目录了):

  http://localhost/test/cookie/father.php

  http://localhost/test/cookie/child/child.php

详谈PHP之cookie的路径_php cookie
<?php//location:  locahost/test/cookie/father.php//setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1);setcookie("father_set_1_/","@@@@",time()+24*3600,"/");setcookie("father_set_2_/child","@@@@",time()+24*3600,"/child/");setcookie("father_set_3_test/cookie/child","@@@@",time()+24*3600,"/test/cookie/child/");print_r($_COOKIE);?>
详谈PHP之cookie的路径_php cookie
详谈PHP之cookie的路径_php cookie
<?php//location:   localhost/test/cookie/child/child.php//setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1);setcookie("child_set_0","@@@@",time()+24*3600);setcookie("child_set_1_/","@@@@",time()+24*3600,"/");setcookie("child_set_2_/child","@@@@",time()+24*3600,"/child");setcookie("child_set_3_/test/cookie/child/","@@@@",time()+24*3600,"/test/cookie/child/");print_r($_COOKIE);?>
详谈PHP之cookie的路径_php cookie

  分别按如下顺序访问页面father.php—>child.php—>father.php—>child.php,使用firebug查看,分别有如下结果:


详谈PHP之cookie的路径_php cookie_05

第一访问father.php


  图中可以看出,本次请求服务端做出响应,打印了$_COOKIE数组,但数组为空。设置了三个cookie值,分别是:"father_set_1_/"、"father_set_2_/child"、"father_set_3_test/cookie/child",它们对应的路径为"/"、"/child"、"/test/cookie/child",其中"/"指的是站点根目录。

  第一次请求father.php时,初始状态下客户端没有相关的cookie记录,在上图中只有已收到的cookie,没有已发送的cookie,则打印$_COOKIE数组时是没有输出。

  从上面这点可以看出,页面的每次请求cookie的变化是:页面请求时浏览器发送客户端已有的cookie,服务器端接收cookie将其存入数组$_COOKIE数组中供程序使用;而在服务器端响应本次请求设置的cookie尚未发送到客户端时$_COOKIE数组中是没有记录的。


详谈PHP之cookie的路径_php cookie_06

第一次访问child.php


  访问child.php能看到请求中发送了两个cookie分别为"father_set_1_/"、"father_set_3_test/cookie/child",接收到四个cookie分别是"child_set_0"、"child_set_1_/"、"child_set_2_/child"、"child_set_3_/test/cookie/child/"。

  页面打印出的$_COOKIE数组中有两个值,分别是请求时发送的数据。

  这里有个貌似奇怪的地方,打印出的$_COOKIE数组只有两个呢,第一个father.php页面不是设置了三个cookie值吗,为什么不能访问"father_set_2_/child"呢?

  这里仔细分析就没有什么奇怪的了,浏览器每次发出请求只发送父级路径和当前路径下的cookie给服务器,服务端的$_COOKIE数组也就是来自每次请求中的发送cookie,这也意味着一个页面只能访问路径设置为当前页面路径和父路径的cookie,不能访问兄弟路径的cookie。


详谈PHP之cookie的路径_php cookie_07

第二次访问father.php


  第二次访问father.php打印出了二个值,也就是本次请求发送了两个值,也就是意味着father.php能访问两个值它们分别是"father_set_1_/"、"child_set_1_/"对应的路径都是"/"。

  这里就能看出来father.php虽然设置了三个cookie,但由于路径的原因浏览器请求时并没有发送其他子路径的cookie以至于不能读取。其中"child_set_1_/"是子路径下的页面设置的cookie,由于路径是本页面所在路径则能读取。

  还有一点值得注意的是,这次访问时没能打印出"child_set_0"的值,在child.php中"child_set_0"的路径是为空的,这点是默认为当前路径,而不是站点根目录的,所有子路径想设置cookie让父路径的页面访问则需要设置路径的。


详谈PHP之cookie的路径_php cookie_08

第二次访问child.php

  再次访问child.php一共能打印出5个值,没能打印出路径为"/child"的cookie,这点说明浏览器只发送“直系”路径关系的cookie值。

总结

  1、服务器端每次访问的cookie是每次请求头中发送给服务器端的

  2、客户端每次请求只发送当前路径下和“直系”关系的父路径的cookie(父路径的页面是不能访问子路径和兄弟路径的cookie的)

  3、setcookie如果不设置路径,默认为当前页面的路径,父亲路径的页面是无法访问的

参考:

  [1] W3school.PHP setcookie() 函数.http://www.w3school.com.cn/php/func_http_setcookie.asp

附件

源码+图片