php如何设置cookie?三种方案比较大全
发布于 作者:苏南大叔 来源:程序如此灵动~

cookie
作为小甜饼,充斥着网络世界。没有了cookie
,那么估计大多数的网站鉴权功能就全部失效了。可见cookie
的重要性。今天苏南大叔,给大家带来的是php
跟cookie
的一些小事情。

- 本文中的实验对象,是纯正的
php
,不夹杂任何任何框架的php
。所以,所有的写法都是原生的,请知晓。 cookie
输出之前,请确保没有任何的页面输出。即使一个空白字符也不行。苏南大叔想起了php
新手经典大坑:php
文件保存为utf8
的时候,必须是nobom
的。
方案一:setcookie
函数
函数说明见这里:http://doc.php.sh/zh/function.setcookie.html 。
$name
不就必说了,cookie的项目名称,一般为个类似“str”的字符串,但是也数组的形式,例如“arr[one]”。$value
传输的过程中会被转义,比如空格会变成加号等,其转义函数,据苏南大叔推断,应该是urlencode。$expire
时间戳,秒数而非毫秒数,cookie的过期时间,是具体的时间点,而非时间段,PHP会对它做进一步的转换为GMT格式。。一般都是控制这个时间为一个过去的时间,来删除掉cookie的。不填或者填0的话,就是浏览器会话期间生效,浏览器关闭即失效。表示过期时间的时候,http协议里面有2个,expire和max-age。目前php里面还是设置expire过期时间的,但是从http协议的角度上看,expire已经开始被max-age取代。expire指的是失效的时间点,max-age是多少秒后失效。$path
cookie的有效目录,一般是和$domain配置使用的,一般设置为/
即可。$domain
这个参数需要重点注意,如果不填的话,则是默认当前域名。如果填写的话,一般来说,也是需要自己用$_SERVER['SERVER_NAME']
获得的域名。并且主动填写的话,最终的cookie作用域是填写的所有子域。如果填写"newsn.net",那么反应到浏览器端,最终的值是“.newsn.net"。注意,前面添加了个".",表示的范围就扩大了。$secure
另外一个很邪门的参数,表示是否仅仅通过安全的 HTTPS 连接传给客户端
。如果设置为true的话,当前网站环境不是https的话,那么这整个cookie就是完全失效的状态。但是,我们通过抓包可以发现,这个cookie已经被php设置,只不过在浏览器端被失效了。而php中,是可以通过isset($_SERVER["HTTPS"])
来判定,是否支持https的。$httponly
这个参数的位置也非常尴尬,是所有可选参数的最后一个。想设置它,就必须先设置$domain
和$secure
这两个似乎可以不必设置的值。而在目前的网络环境里面,$httponly 又应该是强烈推荐设置值。具体情况请参见苏南大叔的后续httponly文章:https://newsn.net/tag/httponly/ 。
所以,很有可能你需要的php
语句是这样的:
方案二:setrawcookie
函数
setrawcookie
和setcookie
,基本一致,区别就在于对$value的处理。下面的两条语句是一致的效果:
特别说明:
urlencode
和rawurlencode
是有区别的,两者的区别不在本篇文章中叙述。需要明确的就是,两者是有区别的。- 当
setrawcookie
的$value
,不进行encode
操作的话,如果里面含有空格的话,整条语句都是失效的。并且不会报错!所以,setrawcookie
必须联合urlencode
才能保证其正确性。但是这个时候,就不如使用setcookie
了。
方案三:header
输出cookie
set cookie
函数,如果想要生效,也是通过header
设置浏览器端进而生效的。所以通过header
输出也是可行的。那么关于写出几条等价的header
操作,大家对比学习一下:


需要注意的是:
- 设置内容的时候,会对特殊字符进行转义。
setcookie
的转义是自动的,header
的转义是主动的。 - 使用
header
的时候,过期时间是个gmt
时间字符串,而setcookie
是个时间戳。 - 设置域名的时候,两者都直接写的域名,但是生效的时候,生效的是.域名,就是说生效范围包括二级域名。
header
比setcookie
好的地方在于:它可以跳过哪些过期时间/域名/path等参数,直接设置httponly
。
最后对比
下面来个php
的cookie
相关函数的终极对决:

这些cookie
值使用了不同的方法进行了设置。里面含有空格和加号。从结果中,我们得出如下结论:
setcookie
和setrawcookie
中的中文,用document.cookie
不能顺利读出,但是用jquery.cookie
可以顺利读出。jquery
的cookie
插件,均正确读取了php
端的各种cookie
值。但是读取header
中的值时,对加号的处理似乎有些问题。document.cookie
,只能正常读取header
设置的中文。即使中文中带有空格,也能正常读取。这也是最正常,表现最好的组合。
总结
表面上看,使用header
设置cookie
和使用setcookie
函数设置cookie
,是可以得到相同的效果的。苏南大叔认为,用header
设置cookie
,比setcookie
更好些。下一篇文章中将继续叙述相关事宜。敬请期待。
在实际操作中,还是有意料之外的事情的。想知道更多关于cookie
的小秘密嘛?那么,请继续关注苏南大叔的cookie
相关文章:


