直击php中unserialize返回false的解决方法
导读:收集整理的这篇文章主要介绍了直击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));
// 正确使用处理过单双引号,过滤\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中unserialize返回false的解决方法的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 直击php中unserialize返回false的解决方法
本文地址: https://pptw.com/jishu/596683.html
