Ben*_*min 6 php oop serialization relationship
关于实现Serializable
接口的对象,我遇到了一个非常棘手的问题.我们来举个例子:
class A {
public $b;
}
class B {
public $a;
}
$a = new A;
$b = new B;
$a->b = $b;
$b->a = $a;
echo serialize($a); // O:1:"A":1:{s:1:"b";O:1:"B":1:{s:1:"a";r:1;}}
echo serialize($b); // O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"b";r:1;}}
$a = unserialize(serialize($a));
var_export($a === $a->b->a); // true
Run Code Online (Sandbox Code Playgroud)
我们可以在这个例子中看到,当使用内置的PHP序列化功能时(无论我们是否使用该__sleep()
函数),A
&之间的交叉引用B
都被保留(r:1;
).
但是,如果我们想强制使用Serializable接口,则会出现问题:
class A implements Serializable {
public $b;
public function serialize() { return serialize($this->b); }
public function unserialize($s) { $this->b = unserialize($s); }
}
class B implements Serializable {
public $a;
public function serialize() { return serialize($this->a); }
public function unserialize($s) { $this->a = unserialize($s); }
}
$a = new A;
$b = new B;
$a->b = $b;
$b->a = $a;
echo serialize($a); // infinite loop crashes PHP
Run Code Online (Sandbox Code Playgroud)
因为每个对象序列化都是独立管理的,所以没有全局方法来查看对象是否已经被序列化,以创建对它的引用.serialize()
然后在无限循环中调用这些函数.
这个问题有一个很好的解决方法吗?用于serialize()
功能的模式?