xPh*_*eRe 5 php spl serialization composite segmentation-fault
我使用SplObjectStorage实现了一个简单的Composite模式,就像上面的例子一样:
class Node
{
private $parent = null;
public function setParent(Composite $parent)
{
$this->parent = $parent;
}
}
class Composite extends Node
{
private $children;
public function __construct()
{
$this->children = new SplObjectStorage;
}
public function add(Node $node)
{
$this->children->attach($node);
$node->setParent($this);
}
}
Run Code Online (Sandbox Code Playgroud)
每当我尝试序列化一个Composite对象时,PHP 5.3.2就会抛出一个Segmentation Fault.只有在向对象添加任意类型的任意数量的节点时才会发生这种情况.
这是违规的代码:
$node = new Node;
$composite = new Composite;
$composite->add($node);
echo serialize($composite);
Run Code Online (Sandbox Code Playgroud)
虽然这个有效:
$node = new Node;
$composite = new Composite;
echo serialize($composite);
Run Code Online (Sandbox Code Playgroud)
另外,如果我使用array()而不是SplObjectStorage实现Composite模式,那么所有运行也都可以.
我做错了什么?
通过设置Parent,您有一个循环引用.PHP将尝试序列化复合,所有的节点和节点反过来将尝试序列化复合..繁荣!
您可以使用魔术__sleep和__wakeup()方法在序列化时删除(或执行任何操作)父引用.
编辑:
看看是否添加这些来Composite修复问题:
public function __sleep()
{
$this->children = iterator_to_array($this->children);
return array('parent', 'children');
}
public function __wakeup()
{
$storage = new SplObjectStorage;
array_map(array($storage, 'attach'), $this->children);
$this->children = $storage;
}
Run Code Online (Sandbox Code Playgroud)