出现问题: 从数据库中取出数据后进行反序列化后,php报错
unserialize(): Error at offset xx of xx
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);
}
demo
public function testUnserialize(){
//
$ss='a:9:{s:3:"mid";s:15:"89832075499APSR";s:3:"tid";s:8:"E85XS7DU";s:10:"merOrderId";s:22:"2022122319435271692711";s:5:"seqId";s:18:"111111111111111111";s:9:"targetSys";s:10:"Alipay
2.0";s:14:"buyerPayAmount";s:3:"100";s:7:"payTime";s:19:"2022-12-23
22:15:15";s:6:"status";s:13:"TRADE_SUCCESS";s:8:"signType";s:6:"SHA256";}';
$ss='O:60:"AlibabaCloud\SDK\Dypnsapi\V20170525\Models\GetMobileResponse":5:{s:8:"*_name";a:3:{s:7:"headers";s:7:"headers";s:10:"statusCode";s:10:"statusCode";s:4:"body";s:4:"body";}s:12:"*_required";a:0:{}s:7:"headers";a:7:{s:4:"Date";a:1:{i:0;s:29:"Sun,
25 Dec 2022 07:41:49
GMT";}s:12:"Content-Type";a:1:{i:0;s:30:"application/json;charset=utf-8";}s:14:"Content-Length";a:1:{i:0;s:3:"125";}s:10:"Connection";a:1:{i:0;s:10:"keep-alive";}s:27:"Access-Control-Allow-Origin";a:1:{i:0;s:1:"*";}s:16:"x-acs-request-id";a:1:{i:0;s:36:"6004E89C-3DDC-54E6-B969-DD8C5C85B152";}s:14:"x-acs-trace-id";a:1:{i:0;s:32:"b669e5a419cebde9b827c0b59ef11e95";}}s:10:"statusCode";N;s:4:"body";O:64:"AlibabaCloud\SDK\Dypnsapi\V20170525\Models\GetMobileResponseBody":6:{s:8:"*_name";a:4:{s:4:"code";s:4:"Code";s:18:"getMobileResultDTO";s:18:"GetMobileResultDTO";s:7:"message";s:7:"Message";s:9:"requestId";s:9:"RequestId";}s:12:"*_required";a:0:{}s:4:"code";s:2:"OK";s:18:"getMobileResultDTO";O:83:"AlibabaCloud\SDK\Dypnsapi\V20170525\Models\GetMobileResponseBody\getMobileResultDTO":3:{s:8:"*_name";a:1:{s:6:"mobile";s:6:"Mobile";}s:12:"*_required";a:0:{}s:6:"mobile";s:11:"18113216448";}s:7:"message";s:2:"OK";s:9:"requestId";s:36:"6004E89C-3DDC-54E6-B969-DD8C5C85B152";}}';
//
$ss = $this->mb_unserialize($ss);
$ss = unserialize($ss);
//
$ret_msg->body->getMobileResultDTO->mobile;
print_r($ss);
}