zoukankan      html  css  js  c++  java
  • 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("
    ", "", $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("
    ", "", $serial_str);      
        return unserialize($serial_str);
    }
  • 相关阅读:
    Ubuntu下手动安装vscode
    VMware Tools安装后设置自动挂载解决共享文件夹无法显示的问题
    VMware Tools安装方法及共享文件夹设置方法
    JavaScript原始类型转换和进制转换
    Javascript的数据类型(原始类型和引用类型)
    设计模式(六)观察者模式
    设计模式(五)之适配器模式
    设计模式(四)注册模式 解决:解决全局共享和交换对象
    设计模式(三)单例模式
    设计模式(二)之策略模式
  • 原文地址:https://www.cnblogs.com/zrp2013/p/4264888.html
Copyright © 2011-2022 走看看