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"  
  • 相关阅读:
    UML与ER图
    动态规划法求背包问题
    回溯法求解n皇后和迷宫问题
    优先队列和二叉堆
    快排,归并和Shell排序
    关系型数据库设计范式
    Python使用Redis数据库
    Python urllib简单使用
    当SQL UPDATE遇到EXISTS(SELECT ...)时
    关于使用mybatis的一个惨痛教训
  • 原文地址:https://www.cnblogs.com/legend-song/p/4896889.html
Copyright © 2011-2022 走看看