php函数unserialize数据返回false问题分析
unserialize的这个问题是由一个emlog论坛用户在使用时报错而发现的
问题表现情况如下:
emlog缓存的保存方式是将php的数据对象(数组)序列化(serialize)后以文件的形式存放,读取缓存的时候直接反序列化(unserialize)缓存字符串即可读取数据。
我从用户那里取到的缓存的序列化数据为:
a:1:{s:8:"kl_album";a:4:{s:5:"title";s:12:"精彩瞬 间";s:3:"url";s:41:"http://www.kaisay.cn/?plugin=kl_album";s:8:"is_blank";s:7:"_parent";s:4:"hide";s:1:"n";}}
咋一看了解序列化的人都会说,这个数据很正常啊,没什么问题呢。可是直接把这段字符串进行unserialize,返回的值却是个False;
代码
var_dump(unserialize('a:1:{s:8:"kl_album";a:4:{s:5:"title";s:12:"精彩瞬间";s:3:"url";s:41:"http://www.kaisay.cn/?plugin=kl_album";s:8:"is_blank";s:7:"_parent";s:4:"hide";s:1:"n";}}'));

运行结果

问题出在哪里呢?答案是 s:41:"http://www.kaisay.cn/?plugin=kl_album"
序列化字符串中标定该字符串http://www.kaisay.cn/?plugin=kl_album的长度是41,可是我们自己数一下却只有37个字符。就是因为这个问题,导致php反序列化字符串失效。
如果将字符串长度改成37,那么程序就会顺利的反序列化
代码:
var_dump(unserialize('a:1:{s:8:"kl_album";a:4:{s:5:"title";s:12:"精彩瞬 间";s:3:"url";s:37:"http://www.kaisay.cn/?plugin=kl_album";s:8:"is_blank";s:7:"_parent";s:4:"hide";s:1:"n";}}'));

通过google后才发现,这个问题国外已经很多的网友遇到了,在官方手册unserialize函数页面的评论中就有很多网友在讨论和研究这个问题的解决方案。
这种情况发生的原因有多种可能,最大的可能就是在序列化数据的时候的编码和反序列化时的编码不一样导致字符串的长度出现偏差。例如数据库编码latin1和UTF-8字符长度是不一样的。
总结:解决方案:
情况一:UTF-8
function mb_unserialize($serial_str) {
$serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
$serial_str= str_replace("\r", "", $serial_str);
return unserialize($serial_str);
}
情况二:ASC
function asc_unserialize($serial_str) {
$serial_str = preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $serial_str );
$serial_str= str_replace("\r", "", $serial_str);
return unserialize($serial_str);
}
php函数unserialize数据返回false问题分析的更多相关文章
- YII2 使用curl请求,返回false
一. 起因: 今天用yii框架,请求java接口,始终返回false. 二. 分析历程: 使用curl_error()方法打印出Peer’s Certificate issuer is not rec ...
- php unserialize 返回false的解决方法
php 提供serialize(序列化) 与unserialize(反序列化)方法. 使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据.(改表结构或者进行下面操 ...
- php fopen函数返回false
使用yum安装的apache2.4.6 php 7.2.2 正确安装后使用fopen()函数打开文件时返回false 百度一下又三种原因 1.目录或者文件夹权限原因 (可以用 chmod - ...
- php 在linux 用fopen() 函数打开,file_get_contents(),fread()函数 读取 另外一台服务器映射过来的文件 总是返回false,null的情况。
php 在linux 用fopen() 函数打开,fread()函数 读取 另外一台服务器映射过来的文件 总是返回false,null的情况. #获取平台类型 $type='android'; ...
- php 在linux 用file_exists() 函数判断 另外一台服务器映射过来的文件是否存在 总是返回false
php 在linux 用file_exists() 函数判断 另外一台服务器映射过来的文件是否存在 总是返回false .如下案例 $type="android"; $url=&q ...
- vue props 下有验证器 validator 验证数据返回true false后,false给default值
vue props 下有验证器 validator 验证数据返回true false后,false给default值 props: { type: { validator (value) { retu ...
- python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False。
python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False. 重难点:定义函数的方法.使用str类型的find()函数,可以 ...
- maftools|TCGA肿瘤突变数据的汇总,分析和可视化
本文首发于公众号“生信补给站”,https://mp.weixin.qq.com/s/WG4JHs9RSm5IEJiiGEzDkg 之前介绍了使用maftools | 从头开始绘制发表级oncoplo ...
- 如何设计PHP业务模块(函数/方法)返回结果的结构?
如题:如何设计业务模块返回结果的结构? 一个业务函数/方法执行后,对外输出数据的结构通常有以下几种: 1.返回数字,如 成功时返回 0,失败时返回 -1,有的还会用一个全局变量输出错误信息: < ...
随机推荐
- sqlserver日志文件缩小
原文:sqlserver日志文件缩小 最近装了个500g的固态硬盘,导入我原来的数据库后发现有60多个G的内存不见了, 最后发现我的某个数据库有60多个G的日志文件(.ldf文件)文件, ...
- [Android Traffic] 使用缓存来避免重复的下载
转载自: http://blog.csdn.net/kesenhoo/article/details/7395817 Redundant Downloads are Redundant[重复下载是冗余 ...
- kubernetes监控--Prometheus
本文基于kubernetes 1.5.2版本编写 kube-state-metrics kubectl create ns monitoring kubectl create sa -n monito ...
- iOS学习4_UITableView的使用
UITableView相当于Android里面的ListView.但功能却比ListView强大太多. 使用UITableView须要指定数据源和代理. 1.显示全部的行 遵守UITableViewD ...
- 【转】javascript 的类,原型,继承的理解
原文: https://www.cnblogs.com/codernie/p/9098184.html ------------------------------------------------ ...
- Laravel之事件
一.事件 事件无处不在,比如用户登录.购买商品.搜索.查看文章,等等,都是事件,有了事件,就有事件监听器,事件监听器监听到事件发生后会执行一些操作,Laravel使用观察者模式来实现这种监听机制.本节 ...
- vue slot slot-scope
https://segmentfault.com/a/1190000012996217 插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示.以及怎样显示由父组件来决定. 实际上,一个s ...
- cocos2d-x 3.0 场景切换特效汇总
cocos2d-x 3.0中场景切换特效比較多,并且游戏开发中也常常须要用到这些特效.来使场景切换时不至于那么干巴,遂这里汇总一下,开发中使用. 场景切换用到导演类Directory,大多数用的都是替 ...
- MySQL + Amoeba 负载均衡、主从备份方案
1. 基本环境 4台内网虚拟机的操作系统都是ubuntu-14.04.4 64位 IP为:192.168.169.11.192.168.169.12.192.168.169.13.192.168.1 ...
- 基于 Token 的身份验证
最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等,比起传统的身份验证方法,Token 扩展性更强, ...