学习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//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//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);?>
分别按如下顺序访问页面father.php―>child.php―>father.php―>child.php,使用firebug查看,分别有如下结果:
第一访问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数组中是没有记录的。
第一次访问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。
第二次访问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让父路径的页面访问则需要设置路径的。
第二次访问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
附件
源码+图片