php 把值存入cookie中,php 序列化存储数组数据到 cookie 中,取出后再反序列化为 false...

不推荐将数组数据通过 serialize() 存储到 cookie 中,因为:Cookie 名称可以设置成数组名称,PHP 脚本里会是数组, 但用户系统里储存的是单独分开的 Cookie。 可以考虑使用 explode() 为一个 Cookie 设置多个名称和值。 不建议将 serialize() 用于此处,因为它会导致安全漏洞。

这边仅作测试使用。以下为测试 demo1:$goods_list = array(

"xx-aa"=>array("price"=>"25.00", "number"=>"10", "title"=>"普通毛巾"),

"yy-bb"=>array("price"=>"36.00", "number"=>"8", "title"=>"精品毛巾"));

ob_start();

header('HTTP/1.1 200');

header('Content-Type:application/json');

var_dump($goods_list);

$goods_serial = serialize($goods_list);

var_dump($goods_serial);

set_cookie('goods_list', $goods_serial);

$goods_serial = get_cookie('goods_list');

var_dump($goods_serial);

$goods_list = unserialize($goods_serial);

var_dump($goods_list);

这份代码在服务器上跑,反序列化后结果为 false。查了 unserialize() 函数注解,传递的字符串不可解序列化会返回 false。也就是说从 cookie 中再次取出来的值与存入的值不等。

因为在本地(php 7.3.2 nts)和个人服务器(php 7.3.2 zts)测试,都是可以正常取出数组,所以可以排除线程安全问题。之后想到可能是 php 版本问题,服务器使用的是 php 5.2.17(很古老的 php 版本了),猜测是低版本环境下,setcookie 做了一些处理导致了值不同。

在 setcookie 函数注解的范例 - 案例#1 中有这样一个说明:注意:在发送 Cookie 时,值的部分会被自动 urlencode 编码。收到 Cookie 时,会自动解码,并赋值到可变的 Cookie 名称上。 如果不想被编码,可以使用 setrawcookie() 代替。

也就是说,正常情况下 setcookie 和 getcookie 会分别使用 urlencode 编码字符串值,urldecode 解码字符串值。那么是不是低版本下缺少了这个步骤呢?测试 demo2 如下:$goods_list = array(

"xx-aa"=>array("price"=>"25.00", "number"=>"10", "title"=>"普通毛巾"),

"yy-bb"=>array("price"=>"36.00", "number"=>"8", "title"=>"精品毛巾"));

ob_start();

header('HTTP/1.1 200');

header('Content-Type:application/json');

var_dump($goods_list);

$goods_serial = urlencode(serialize($goods_list));

var_dump($goods_serial);

set_cookie('goods_list', $goods_serial);

$goods_serial = get_cookie('goods_list');

var_dump($goods_serial);

$goods_list = unserialize(urldecode($goods_serial));

var_dump($goods_list);

结果数组正常正常解析出来了。然后就有了使用 json_encode 和 json_decode 版本(serialize() 存在漏洞,不安全)demo3:$goods_list = array(

"xx-aa"=>array("price"=>"25.00", "number"=>"10", "title"=>"普通毛巾"),

"yy-bb"=>array("price"=>"36.00", "number"=>"8", "title"=>"精品毛巾"));

ob_start();

header('HTTP/1.1 200');

header('Content-Type:application/json');

var_dump($goods_list);

$goods_serial = urlencode(json_encode($goods_list));

var_dump($goods_serial);

set_cookie('goods_list', $goods_serial);

$goods_serial = get_cookie('goods_list');

var_dump($goods_serial);

$goods_list = json_decode(urldecode($goods_serial), true);

var_dump($goods_list);

一开始可能因为 urldecode 位置放错了,没有成功,然后观察了中间刚取出 cookie 的值,发现了 unserialize() 反序列化失败的真正原因:php 5.2.17 版本 setcookie 存入的值使用了 addslashes() 函数做转义处理,但 getcookie 取出时没有自动调用 stripslashes() 取消转义。

针对这个问题,可以在取出 cookie 之后增加一步取消处理即可:$goods_serial = stripslashes($goods_serial);

后续 php 版本修复了这个 bug,在 cookie 读写函数内部采用了 urlencode 和 urldecode 方法处理数据。而低版本中使用 urlencode 和 urldecode 方法也可以解决这个 bug,因为 url 转码恰好修改了需要转义的项,使 addslashes() 无功而返,最终解码成功。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值