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问题分析的更多相关文章

  1. YII2 使用curl请求,返回false

    一. 起因: 今天用yii框架,请求java接口,始终返回false. 二. 分析历程: 使用curl_error()方法打印出Peer’s Certificate issuer is not rec ...

  2. php unserialize 返回false的解决方法

    php 提供serialize(序列化) 与unserialize(反序列化)方法. 使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据.(改表结构或者进行下面操 ...

  3. php fopen函数返回false

    使用yum安装的apache2.4.6   php 7.2.2  正确安装后使用fopen()函数打开文件时返回false 百度一下又三种原因 1.目录或者文件夹权限原因 (可以用   chmod - ...

  4. php 在linux 用fopen() 函数打开,file_get_contents(),fread()函数 读取 另外一台服务器映射过来的文件 总是返回false,null的情况。

    php 在linux 用fopen() 函数打开,fread()函数 读取  另外一台服务器映射过来的文件 总是返回false,null的情况. #获取平台类型   $type='android';  ...

  5. php 在linux 用file_exists() 函数判断 另外一台服务器映射过来的文件是否存在 总是返回false

    php 在linux 用file_exists() 函数判断 另外一台服务器映射过来的文件是否存在 总是返回false .如下案例 $type="android"; $url=&q ...

  6. vue props 下有验证器 validator 验证数据返回true false后,false给default值

    vue props 下有验证器 validator 验证数据返回true false后,false给default值 props: { type: { validator (value) { retu ...

  7. python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False。

    python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False. 重难点:定义函数的方法.使用str类型的find()函数,可以 ...

  8. maftools|TCGA肿瘤突变数据的汇总,分析和可视化

    本文首发于公众号“生信补给站”,https://mp.weixin.qq.com/s/WG4JHs9RSm5IEJiiGEzDkg 之前介绍了使用maftools | 从头开始绘制发表级oncoplo ...

  9. 如何设计PHP业务模块(函数/方法)返回结果的结构?

    如题:如何设计业务模块返回结果的结构? 一个业务函数/方法执行后,对外输出数据的结构通常有以下几种: 1.返回数字,如 成功时返回 0,失败时返回 -1,有的还会用一个全局变量输出错误信息: < ...

随机推荐

  1. 【转】Kriging插值法

    einyboy 原文LINK Kriging插值法 克里金法是通过一组具有 z 值的分散点生成估计表面的高级地统计过程.与插值工具集中的其他插值方法不同,选择用于生成输出表面的最佳估算方法之前,有效使 ...

  2. Sync 攻击原理及防范技术

    据统计,在所有黑客攻击事件中,SYN攻击是最常见又最容易被利用的一种攻击手法.相信很多人还记得2000年YAHOO网站遭受的攻击事例,当时黑客利用的就是简单而有效的SYN攻击,有些网络蠕虫病毒配合SY ...

  3. python的__call__、__str__、__repr__、__init__、__class__、__name___、__all__、__doc__、__del__等魔术方法的作用

    python中,一切都是对象 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”--魔术方法 1.__call__:作用是把类实例变成一个可调用对象 在Pyth ...

  4. Maven配置Spring+Hibernate Shiro权限控制项目

    前言:在Eclipse中安装好Maven插件,然后创建一个Sample项目.在Eclipse中检出Shiro的官方演示样例.地址http://svn.apache.org/repos/asf/shir ...

  5. JS或jQuery获取当前屏幕宽度

    Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document.b ...

  6. PHP使用mysqli连接MySQL数据库

    使用mysqli函数库连接MySQL,支持面向对象和面向过程两种方式: 1.面向对象的使用方式 建立一个连接 $db = new mysqli('localhost', 'root', '123456 ...

  7. Android 完美退出 App 方法

    大家都知道 Android 的 Activity 是存着历史栈的,比如从 A -> B -> C,C 完成 finish 后回到 B,把所有的Activity 都 finish了,程序就自 ...

  8. Angular 学习笔记——ng-Resource1

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  9. Spring IOC源代码具体解释之容器初始化

    Spring IOC源代码具体解释之容器初始化 上篇介绍了Spring IOC的大致体系类图,先来看一段简短的代码,使用IOC比較典型的代码 ClassPathResource res = new C ...

  10. 基于RxJava2+Retrofit2精心打造的Android基础框架

    代码地址如下:http://www.demodashi.com/demo/12132.html XSnow 基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络.上传.下载 ...