首页后端开发PHP直击php中unserialize返回false的解决方法

直击php中unserialize返回false的解决方法

时间2024-02-02 09:51:03发布访客分类PHP浏览685
导读:收集整理的这篇文章主要介绍了直击php中unserialize返回false的解决方法,觉得挺不错的,现在分享给大家,也给大家做个参考。本文实例讲述了php中unserialize返回false的解决方法,分享给大家供大家参考。具体方法如下...
收集整理的这篇文章主要介绍了直击php中unserialize返回false的解决方法,觉得挺不错的,现在分享给大家,也给大家做个参考。

本文实例讲述了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));
     // 正确

使用处理过单双引号,过滤\rmb_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中unserialize返回false的解决方法的详细内容,更多请关注其它相关文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: 直击php中unserialize返回false的解决方法
本文地址: https://pptw.com/jishu/596683.html
想学php编程?那你必看这些书 PHP 进程管理器 PHP-FPM

游客 回复需填写必要信息