cookie作为小甜饼,充斥着网络世界。没有了cookie,那么估计大多数的网站鉴权功能就全部失效了。可见cookie的重要性。今天给大家带来的是php跟cookie的一些小事情。本文中的实验对象,是纯正的php,不夹杂任何任何框架的php。所以,所有的写法都是原生的,请知晓。

cookie输出之前,请确保没有任何的页面输出。即使一个空白字符也不行。苏南大叔想起了php新手经典大坑:php文件保存为utf8的时候,必须是nobom的。

方案一:setcookie函数

PHPbool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )

函数说明见这里:https://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语句是这样的:

PHPsetcookie("cookie_name", "cookie_value", time() + 3600, "/", $_SERVER['SERVER_NAME'], isset($_SERVER["HTTPS"]), true);

方案二:setrawcookie函数

PHPbool setrawcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool$ httponly = false ]]]]]] )

setrawcookie和setcookie,基本一致,区别就在于对$value的处理。下面的两条语句是一致的效果:

PHPsetcookie($name,$value);setrawcookie($name,urlencode($value));

特别说明:urlencode和rawurlencode是有区别的,两者的区别不在本篇文章中叙述。需要明确的就是,两者是有区别的。

当setrawcookie的$value,不进行encode操作的话,如果里面含有空格的话,整条语句都是失效的。并且不会报错!所以,setrawcookie必须联合urlencode才能保证其正确性。但是这个时候,就不如使用setcookie了。

方案三:header输出cookie

set cookie函数,如果想要生效,也是通过header设置浏览器端进而生效的。所以通过header输出也是可行的。那么关于写出几条等价的header操作,大家对比学习一下:

PHPheader("Set-Cookie:cookie_name1_cp=" . urlencode("浏览器关闭失效"));setcookie("cookie_name1", "浏览器关闭失效");

PHPheader("Set-Cookie:cookie_name=" . urlencode("设置有效域名/https/httponly") . "; expires=" . gmstrftime("%a, %d-%b-%Y %H:%M:%S GMT", time() + 3600*24) . "; Max-Age=3600; path=/; domain= ".$_SERVER['SERVER_NAME']."; httponly");setcookie("cookie_name3", "设置有效域名/https/httponly", time() + 3600*24, "/", $_SERVER['SERVER_NAME'], isset($_SERVER["HTTPS"]),true);

需要注意的是:设置内容的时候,会对特殊字符进行转义。setcookie的转义是自动的,header的转义是主动的。

使用header的时候,过期时间是个gmt时间字符串,而setcookie是个时间戳。

设置域名的时候,两者都直接写的域名,但是生效的时候,生效的是.域名,就是说生效范围包括二级域名。

header比setcookie好的地方在于:它可以跳过哪些过期时间/域名/path等参数,直接设置httponly。

最后对比

下面来个php的cookie相关函数的终极对决:

PHP<?php

$val="我是中文 newsn.net";setcookie("cookie_normal",$val);setrawcookie("cookie_raw",urlencode($val));setrawcookie("cookie_raw2",rawurlencode($val));header("Set-Cookie:cookie_header=带 空 + 格 的中文",false);?>

document.write(document.cookie+"

normal:"+cookie_normal+",
raw:"+cookie_raw+",
raw2:"+cookie_raw2+",
header:"+cookie_header);

这些cookie值使用了不同的方法进行了设置。里面含有空格和加号。从结果中,我们得出如下结论:setcookie和setrawcookie中的中文,用document.cookie不能顺利读出,但是用jquery.cookie可以顺利读出。

jquery的cookie插件,均正确读取了php端的各种cookie值。但是读取header中的值时,对加号的处理似乎有些问题。

document.cookie,只能正常读取header设置的中文。即使中文中带有空格,也能正常读取。这也是最正常,表现最好的组合。

总结

表面上看,使用header设置cookie和使用setcookie函数设置cookie,是可以得到相同的效果的。苏南大叔认为,用header设置cookie,比setcookie更好些。下一篇文章中将继续叙述相关事宜。敬请期待。

在实际操作中,还是有意料之外的事情的。

php操作cookie_php设置cookie【三种方案】相关推荐

  1. Spring Boot 实现单点登录的第三种方案!

    前面松哥发过两篇文章,也是两种方案,讲到单点登录问题: OAuth2+JWT 方案 @EnableOAuth2Sso 注解方案 今天再来和大家介绍第三种方案,使用 Spring Security 开发 ...

  2. 分布式锁解决并发三种方案

    目录 为什么使用分布式锁? 分布式锁应具备的条件 三种实现方式 1.数据库锁 1.1 乐观锁 2.基于redis的分布式锁 3.基于Zookeeper实现分布式锁 4.三种方案的比较 分布式CAP理论 ...

  3. JS 异步加载js的三种方案

    js文件同步加载的缺点: 页面的js文件一般是同步加载,加载到js文件会阻断html和css的加载,要等到js文件加载完毕,才能继续向下执行,因为js文件可能会操作html和css:但有些js文件不会 ...

  4. 【Win 10 应用开发】文件读写的三种方案

    本文老周就跟伙伴们探讨一下关于文件读写的方法.总得来说嘛,有三种方案可以用,而且每种方案都各有特色,也说不上哪种较好.反正你得记住老祖宗留给我们的大智慧--事无定法,灵活运用者为上. OK,咱们开始吧 ...

  5. sql优化之:数据库索引创建原则,or/in/union与索引优化,聚集索引/非聚集索引/联合索引/索引覆盖,MySQL冗余数据的三种方案,MySQL双主一致性架构优化(来源:架构师之路)

    一.一些常见的SQL实践 (1)负向条件查询不能使用索引 select * from order where status!=0 and stauts!=1 not in/not exists都不是好 ...

  6. Web应用中避免Form重复提交的三种方案

    Web应用中避免Form重复提交的三种方案 2007-08-21 18:29 Web应用中重复提交的问题的三种解决方案 前两种是利用javascript,后面一种是在使用Struts的情况下的参考实现 ...

  7. 华为交换机重制_华为交换机恢复出厂设置的三种方法

    原标题:华为交换机恢复出厂设置的三种方法 当交换机利旧使用时,一般会把交换机恢复出厂设置,并升级到最新版本. 准备工作 如果利旧的交换机是已经使用过的,可保存交换机恢复出厂设置前的配置,可用于交换机的 ...

  8. 网页的横向打印的三种方案(print your page landscape)

    关于网页打印,window.print()提供的功能离远离一般的需求,很多情况下需要编程扩展 目前网上有很多关于网页打印的,但大多采用了ActiveX控件或IE内置的一些Object,由于Active ...

  9. iphone复制不能全选_IOS默认全选复制的三种方案

    类似于textField,长按就会默认跳出复制的选项,但是默认选中的就是你手指点击的那个文字,想全选的话必须手动选择全选才可以,而最近碰到一个需求就是要点击文字,默认就是选中所有的文字,比如游戏中的邀 ...

最新文章

  1. matlab 图像平滑的算法_图像相似度---灰度分布算法---用matlab实现
  2. Android语言国际化values资源文件命名规则
  3. RTX移植到STM32F103
  4. mysql 案例~ 主从复制转化为级联复制
  5. “出题老师”超全划重点,赛场高分必备干货!
  6. 多媒体系统导论 实验二 基于Premiere的视频处理
  7. matlab 三角函数积分,正弦函数与三角函数积分及Matlab编程.doc
  8. 微信发红包的测试点有哪些? 评论/点赞/分享/收藏/收索/上传/下载
  9. 2022道路运输企业安全生产管理人员考试题及答案
  10. maven配置阿里镜像
  11. 什么是微内核,看这一篇就够了
  12. 金蝶虚拟化客户端连不上服务器,金蝶kis客户端远程连接服务器
  13. 最美的十大经典爱情句子{转}
  14. 在算力“沃土”上,种植互联网下一个奇迹十年
  15. python打印日历小项目
  16. echarts引导线_如何使用引导线获得更清晰的照片
  17. 第8章 对象引用、可变性和垃圾回收
  18. 2021物联网开发学习——基于小熊派IoT开发板Bear-Pi-IOT、E53_IA1_智慧农业拓展板与小熊派-鸿蒙·季Bear-Pi-HM Nano并接入Hi-Link
  19. 数据库练习题(KDWY题库)
  20. QQ正式上线QID功能,用户可自定义独一无二的专属身份卡

热门文章

  1. 强悍的命令行 —— basename 去掉路径和扩展名 dirname 获取路径
  2. 机器学习实践指南(四)—— 算法的细节
  3. Spark 机器学习 —— 从决策树到随机森林
  4. web和python前景_我想了解一下pythonweb和javaweb比较详细的学习成本和应用前景,谢谢!?...
  5. JAVA控制台扑克牌游戏,洗牌,发牌,比较大小
  6. 财务有必要学python吗-工作三年却被实习生抢了饭碗,学会Python到底有多吃香?...
  7. python做excel自动化-Python控制Excel实现自动化办公
  8. python从入门到精通pdf百度云-跟老齐学Python:从入门到精通 完整版PDF[7MB]
  9. python从入门到精通-终于懂得python从入门到精通教程
  10. python免费教程视频-Python免费视频教程