PHP - setcookie函数

日期 2018-12-14
Coding/编程
作者 Webster Zhang

前言

考完试了以后感觉自己跟一条咸鱼没啥区别了,每天对着电脑总感觉啥也没干一天就过去了。本着人总得干点什么事情让自己不那么无聊的原则,决定捡起PHP学点什么。然后,在我写登录的token生成算法的时候,我就卡在了setcookie这里。
PHP_the_best_language

Cookie 和 Session

既然都拿出来写文章了,总得研究下Cookie到底是个什么东西。简单地来说Cookie可以理解成是一个写在客户端或浏览器里面的变量或“记号”。Cookie的存在是为了方便网站进行用户识别和跟踪,近年来一直存在隐私和安全性的争议。有一个东西和Cookie作用非常相近,叫做session。只不过Session的数据是保存在服务器的,而且Session有可能也需要通过Cookie来实现。Cookie是有有效期的,一个在正常的浏览器里保存的Cookie一旦过期,在一般情况下会触发浏览器的垃圾回收机制,然后浏览器就会把这个Cookie变成不可用的状态然后转身出门丢进垃圾堆里。那么Cookie可不可以设置成永远不会过期呢?嗯……其实并没有这种操作。但是人们可以通过把这个Cookie的有效期设置成一个特别长的时间来近似达到永远不过期的效果。(如果非要加上一个期限,我希望是一万年)
expired_session

setcookie函数

首先我们来看看官方的手册是怎么描述的。

bool setcookie ( string $name [, string $value = "" [, int $expires = 0 [, string $path = "" [, string $domain = "" [, bool $secure = FALSE [, bool $httponly = FALSE ]]]]]] )

简单点就是这样:

bool setcookie ( string 变量名, string 变量值, int 过期时间, string 路径, string 作用域, bool 安全性, bool 仅限HTTP协议 )

我直接就关注到了前三个。

  • 变量名: cookie的名字
  • 变量值: cookie的值
  • 过期时间: 如其名,默认为0。

于是乎,我就使用了如下的语句来设置我的cookie。

setcookie('token', generateToken($id), 3600);

结果在测试的时候,当我登录的逻辑执行完毕跳转到首页时,网页用JavaScript获得token的值。然后,就是拿不回来我刚刚设置的token……

解决过程

后来去问了一下各种搜索引擎,然后又仔细地看了一下手册里的描述。我发现手册在描述过期时间时,上面写的是:This is a Unix timestamp,突然发觉自己犯傻了。这里的过期时间应该填一个时间戳,而不是直接写一个秒数。于是代码变成了这样。

setcookie('token', generateToken($id), time() + 3600);

然后再测试,还是拿不到。于是又搜索了一番以后找到了答案。答案藏在后面的$path参数里。原来一个Cookie是有自己的有效域和有效路径的。在子路径里设置的cookie在跳转到其父路径下以后是没办法获取的。比如我在/api/setcookie.php下设置一个cookie,这个cookie在/index.html里是没办法直接获取的。这个时候就得看第四第五个参数了。

  • 路径: cookie的有效路径,指的是当前目录和当前目录的子目录
  • 作用域: 域名限制,这里写一个域名,不包括子域名,需要考虑跨域访问的问题

这样一来就好解决了,改成这样

setcookie('token', generateToken($id), time + 3600, "/"); // 第四个参数指把cookie设置在根目录下

测试以后,问题解决,又水一篇。

参考