欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

unserialize(): Error at offset 154 of 164 bytes unserialize(): Error at offset 0 of 96 bytes出现的原因分析以及解决方法 有大用

出现问题: 从数据库中取出数据后进行反序列化后,php报错  unserialize(): Error at offset 0 of 96 bytes;

分析原因:英文数据中含有中文字符串,所以我们就可以想到编码的问题,serialize()函数对在不同编码下对中文的处理结果是不一样的。

再讲gbk转换成utf8的格式后,每个中文的编码数从2个会增加到3个,所以会导致反序列化的时候判断字符长度出现问 

解决方法 : 使用正则表达式将序列化的数组中的表示字符长度的值重新计算一遍

具体代码:php5.5以下 :

function mb_unserialize($str) {
    $out = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $str );
    return unserialize($out);
}


但是由于PHP本身 /e模式的漏洞,php5.5+,已经废弃了这种用法


PHP 5.5+

function mb_unserialize($str) {
    return preg_replace_callback('#s:(\d+):"(.*?)";#s',function($match){return 's:'.strlen($match[2]).':"'.$match[2].'";';},$str);
}


来自  https://blog.csdn.net/glx490676405/article/details/79041405


unserialize(): Error at offset出现的原因分析以及解决方法

unserialize(): Error at offset出现的原因分析以及解决方法

在PHP的unserialize函数使用中,当字符串或数据库中取出的数据有中文的时候,会出现如下错误

Notice: unserialize(): Error at offset xx of xxx bytes in C:\toolmao\php\index.php on line 21

说到中文,我们肯定第一时间想到编码,那么让我们看看不同文件编码下 serialize 函数对中文的处理是怎么样的,用同一段代码,文件用不同编码来测试

echo serialize(array('name'=>'工具猫','url'=>'http://www.toolmao.com/'));

首先看看UTF8的效果,我们发现 中文 “工具猫”的长度是 9

1

而文件编码是GB2312的时候,中文“工具猫”的长度是 6

2

所以当我们取出数据库编码为GBK等中文编码,后又用转码函数转成UTF8后,再用unserialize函数时,因为中文在不同编码下的长度不同,就会出现这个问题了。有人可能会说,数据库取出的时候 SET NAMES 不就行了,但有些数据库(比如access和sqlite)是不支持这样操作的。所以编码不符的时候,必须取出数据转码了。那么具体要如何操作呢?接下来就讲解决方案:

上面我们已经知道了unserialize出现Error at offset报错的成因,那么解决起来就简单了,用正则函数把错误的长度替换掉就可以了,网上已经有大神给出了现成的代码:

unserialize(preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $string))
出自:http://www.phpddt.com/php/unserialize-error-at-offset.html

但是由于php的原因,/e 模式存在漏洞,所以php5.5以后取消了这样的用法,所以使用php5.5+的小伙伴们不要急,这里提供另一个解决方案

preg_replace_callback('#s:(\d+):"(.*?)";#s',function($match){return 's:'.strlen($match[2]).':"'.$match[2].'";';},$data);


来自  https://blog.csdn.net/zdw19861127/article/details/52848889

普通分类: