zoukankan      html  css  js  c++  java
  • php unserialize 返回false的解决方法

    php 提供serialize(序列化) 与unserialize(反序列化)方法。

    使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。(改表结构或者进行下面操作)

    1. <?php  
    2. $arr = array(  
    3.     'name' => 'fdipzone',  
    4.     'gender' => 'male'  
    5. );  
    6.   
    7. $str = serialize($arr); //序列化  
    8. echo 'serialize str:'.$str." ";  
    9.   
    10. $content = unserialize($str); // 反序列化  
    11. echo "unserialize str: ";  
    12. var_dump($content);  
    13. ?>  

    输出:

    1. serialize str:a:2:{s:4:"name";s:8:"fdipzone";s:6:"gender";s:4:"male";}  
    2.   
    3. unserialize str:  
    4. array(2) {  
    5.   ["name"]=>  
    6.   string(8) "fdipzone"  
    7.   ["gender"]=>  
    8.   string(4) "male"  
    9. }  


    但下面这个例子反序列化会返回false

    1. <?php  
    2. $str = 'a:9: {s:4:"time";i:1405306402;s:4:"name";s:6:"新 晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com /test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:" 中国北京市 北京市移动";s:4:"miao";s:1:"5";}';  
    3. var_dump(unserialize($str)); // bool(false)  
    4. ?>  


    检查序列化后的字符串,发现出问题是在两处地方

    s:5:"url"

    s:29:"http://www.baidu.com/test.html"

    这两处应为

    s:3:"url"

    s:30:"http://www.baidu.com/test.html"


    出现这种问题的原因是序列化数据时的编码与反序列化时的编码不一致导致,例如数据库是latin1和UTF-8字符长度不一样。

    另外有可能出问题的还有单双引号,ascii字符""被解析为 '',在C中是字符串的结束符等于chr(0),错误解析后算了2个字符。

    在计算长度时也会出问题。


    解决方法如下:

    1. // utf8  
    2. function mb_unserialize($serial_str) {  
    3.     $serial_str= preg_replace('!s:(d+):"(.*?)";!se', "'s:'.strlen('$2').':"$2";'", $serial_str );  
    4.     $serial_str= str_replace(" ", "", $serial_str);  
    5.     return unserialize($serial_str);  
    6. }  
    7.   
    8. // ascii  
    9. function asc_unserialize($serial_str) {  
    10.     $serial_str = preg_replace('!s:(d+):"(.*?)";!se', '"s:".strlen("$2").":"$2";"', $serial_str );  
    11.     $serial_str= str_replace(" ", "", $serial_str);  
    12.     return unserialize($serial_str);  
    13. }  


    例子:

    1. echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">';  
    2.   
    3. // utf8  
    4. function mb_unserialize($serial_str) {  
    5.     $serial_str= preg_replace('!s:(d+):"(.*?)";!se', "'s:'.strlen('$2').':"$2";'", $serial_str );  
    6.     $serial_str= str_replace(" ", "", $serial_str);  
    7.     return unserialize($serial_str);  
    8. }  
    9.   
    10. $str = 'a:9: {s:4:"time";i:1405306402;s:4:"name";s:6:"新 晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com /test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:" 中国北京市 北京市移动";s:4:"miao";s:1:"5";}';  
    11.   
    12. var_dump(unserialize($str));    // false  
    13.   
    14. var_dump(mb_unserialize($str)); // 正确  


    使用处理过单双引号,过滤 的mb_unserialize方法就能成功反序列化了。

      1. 使用unserialize  
      2. bool(false)  
      3.   
      4. 使用mb_unserialize  
      5. array(9) {  
      6.   ["time"]=>  
      7.   int(1405306402)  
      8.   ["name"]=>  
      9.   string(6) "新晨"  
      10.   ["url"]=>  
      11.   string(1) "-"  
      12.   ["word"]=>  
      13.   string(1) "-"  
      14.   ["rpage"]=>  
      15.   string(30) "http://www.baidu.com/test.html"  
      16.   ["cpage"]=>  
      17.   string(1) "-"  
      18.   ["ip"]=>  
      19.   string(15) "117.151.180.150"  
      20.   ["ip_city"]=>  
      21.   string(31) "中国北京市 北京市移动"  
      22.   ["miao"]=>  
      23.   string(1) "5"  
  • 相关阅读:
    设置vim查找高亮
    设置vim显示行号
    虚拟机安装VMware tools
    硬链接和软链接
    Ubuntu用户首次设置root用户的密码
    Ubuntu无法远程连接
    线上教育课堂如何解决H5视频点播转码出现的黑屏问题?
    “音视频+”时代到来,HLS(m3u8)/HTTP-FLV/RTSP流媒体RTMP推流服务器EasyDSS应用场景优化
    搭建一套完整的网络视频流媒体直播/点播服务系统需要具备哪些条件?
    关于网络视频流媒体直播/点播服务流程,你要知道的全在这里了!(新手必看)
  • 原文地址:https://www.cnblogs.com/legend-song/p/4896889.html
Copyright © 2011-2022 走看看