关于tp6的unserialize() Error at offset 76 of 176 bytes报错
前段经常看同事的接口bug是报这个错:“unserialize() Error at offset 76 of 176 bytes",
然后清理下缓存就不报错了,虽然觉得诡异,但由于事情比较多,也没时间去深究。
今天在处理关于客服系统的问题的时候,也遇到了这个问题,就索性探一探究竟。
首先可以确定的是,报错的地方是在缓存cache()的底层逻辑,背景是客服系统的框架是tp5,
客户系统的框架是tp6;于是对比了下两个版本的cache,
发现tp6的cache在存入、取出缓存的驱动(Driver.php)上做了很大的改动
tp5的存入取出代码如下:
/**
* 序列化数据
* @access protected
* @param mixed $data
* @return string
*/
protected function serialize($data)
{
if (is_scalar($data) || !$this->options['serialize']) {
return $data;
}
$serialize = self::$serialize[0];
return self::$serialize[2] . $serialize($data);
}
/**
* 反序列化数据
* @access protected
* @param string $data
* @return mixed
*/
protected function unserialize($data)
{
if ($this->options['serialize'] && 0 === strpos($data, self::$serialize[2])) {
$unserialize = self::$serialize[1];
return $unserialize(substr($data, self::$serialize[3]));
} else {
return $data;
}
}
$serialize 参数的值
/**
* 序列化方法
* @var array
*/
protected static $serialize = ['serialize', 'unserialize', 'think_serialize:', 16];
tp6的存入取出代码如下:
/**
* 序列化数据
* @access protected
* @param mixed $data 缓存数据
* @return string
*/
protected function serialize($data): string
{
if (is_numeric($data)) {
return (string) $data;
}
$serialize = $this->options['serialize'][0] ?? "serialize";
return $serialize($data);
}
/**
* 反序列化数据
* @access protected
* @param string $data 缓存数据
* @return mixed
*/
protected function unserialize(string $data)
{
if (is_numeric($data)) {
return $data;
}
$unserialize = $this->options['serialize'][1] ?? "unserialize";
return $unserialize($data);
}
看到这里,大概就知道为什么在tp6获取cache值的时候会报这个错了。
tp5的存入值是否加serialize序列化是判断传入$data是否是标量is_scalar,
而tp6是判断是否为数值is_numeric,导致两边数据不一致。
知道了原因,解决方法就个显神通了,当前的方式比较粗暴,直接修改底层框架,
在tp6 unserialize的方法里面修改判断是否反序列化的逻辑,代码如下:
/**
* 反序列化数据
* @access protected
* @param string $data 缓存数据
* @return mixed
*/
protected function unserialize(string $data)
{
//判断$data是否为序列化字符串,如果不是直接返回不需要反序列化
if (!preg_match( '/^[asO]:[0-9]+:/s', $data)) {
return $data;
}
$unserialize = $this->options['serialize'][1] ?? "unserialize";
return $unserialize($data);
}
本文由 我爱PHP169 作者:admin 发表,其版权均为 我爱PHP169 所有,文章内容系作者个人观点,不代表 我爱PHP169 对观点赞同或支持。如需转载,请注明文章来源。