• 技术文章 >后端开发 >PHP问题

    php反序列化失败怎么办

    藏色散人藏色散人2020-09-12 10:18:14原创824

    php反序列化失败是因为序列化数据时的编码与反序列化时的编码不一致导致的,其解决办法就是使用处理过的单双引号,过滤“\r”的“mb_unserialize”方法即可成功反序列化。

    推荐:《PHP视频教程

    php unserialize 返回false的解决方法

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

    使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。

    <?php
    $arr = array(
        'name' => 'fdipzone',
        'gender' => 'male'
    );
    
    $str = serialize($arr); //序列化
    echo 'serialize str:'.$str."\r\n\r\n";
    
    $content = unserialize($str); // 反序列化
    echo "unserialize str:\r\n";
    var_dump($content);
    ?>

    输出:

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

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

    <?php
    $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";}';
    var_dump(unserialize($str)); // bool(false)
    ?>

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

    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字符"\0"被解析为 '\0',\0在C中是字符串的结束符等于chr(0),错误解析后算了2个字符。

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

    解决方法如下:

    // utf8
    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);
    }
    
    // ascii
    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);
    }

    例子:

    echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">';
    
    // utf8
    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);
    }
    
    $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";}';
    
    var_dump(unserialize($str));    // false
    
    var_dump(mb_unserialize($str)); // 正确

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

    使用unserialize
    bool(false)
    
    使用mb_unserialize
    array(9) {
      ["time"]=>
      int(1405306402)
      ["name"]=>
      string(6) "新晨"
      ["url"]=>
      string(1) "-"
      ["word"]=>
      string(1) "-"
      ["rpage"]=>
      string(30) "http://www.baidu.com/test.html"
      ["cpage"]=>
      string(1) "-"
      ["ip"]=>
      string(15) "117.151.180.150"
      ["ip_city"]=>
      string(31) "中国北京市 北京市移动"
      ["miao"]=>
      string(1) "5"
    }

    以上就是php反序列化失败怎么办的详细内容,更多请关注php中文网其它相关文章!

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:php 反序列化
    上一篇:php如何实现ftp上传 下一篇:yum php版本太低怎么办
    大前端线上培训班

    相关文章推荐

    • 直击PHP序列化和反序列化原理• php之json与xml序列化/反序列化• 详解PHP的session反序列化漏洞问题• 详解PHP序列化和反序列化

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网