关于 PHP 序列化和反序列化不得不知道的细节 (待确认)
在开发
例如:下载中心导出的任务需要将处理类序列化到数据库,或者Redis
例如:队列任务需要将处理类序列化到 Redis 等
像如此常见的序列化操作,有很大几率出错是很正常的
我们定义两个类来测试
class A {
protected $class;
public function __construct($class) {
$this->class = $class;
}
public function dd() {
$this->class->d();
}
}
class B {
protected $x;
protected $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
public function d() {
echo "Hello";
}
}
我们需要这样子输出
- 如果是直接传入
类
到类属性
并且直接执行,那么是能够正常输出的$b = new B(1,2); $a = new A($b); $a->dd();
如果我们序列化呢?
- 先在程序中序列化
$a = serialize($a);
- 然后序列化得到字符串
O:1:"A":1:{s:8:" * class";O:1:"B":2:{s:4:" * x";i:1;s:4:" * y";i:2;}}
- 然后我们在另外一个程序进行反序列化并且执行
$a->dd()
$a = '<上面的序列化后的字符串,输入会导致格式显示问题,所以我就不输入了>'; $a = unserialize($a); $a->dd();
- 对的,你没看错,报错了,居然报错了!!!
PS D:\data\文档> php a.php Fatal error: Uncaught Error: Call to a member function d() on null in D:\data\文档\a.php:11 Stack trace: #0 D:\data\文档\a.php(31): A->dd() #1 {main} thrown in D:\data\文档\a.php on line 11
结论
- 在使用序列化的函数,允许对
类的继承
进行序列化 (大家可以去测试一下,是正常的) - 在使用序列化的函数,允许对
基本属性
进行序列化 - 在使用序列化的函数,不允许
将别的类
传入到类属性中
进行序列化
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: