开发者

Error serializing an object tree with SplObjectStorage

开发者 https://www.devze.com 2023-01-13 15:47 出处:网络
I have implemented a simple Composite pattern using SplObjectStorage, like the example above: class Node

I have implemented a simple Composite pattern using SplObjectStorage, like the example above:

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);
    }
}

Whenever I try to serialize a Composite object, PHP 5.3.2 throws me a Segmentation Fault. This only happens when I add any number of nodes of any type to the object.

This is the offending code:

$node = new Node;
$composite = new Composite;
$composite->add($node);
echo serialize($composite);

Although this one works:

$node =开发者_开发百科 new Node;
$composite = new Composite;
echo serialize($composite);

Also, if I implement the Composite pattern with array() instead of SplObjectStorage, all runs ok too.

What I'm making wrong?


By setting the Parent, you have a circular reference. PHP will try to serialize the composite, all of it's nodes and the nodes in turn will try to serialize the composite.. boom!

You can use the magic __sleep and __wakeup() methods to remove (or do whatever to the) the parent reference when serializing.

EDIT:

See if adding these to Composite fixes the issue:

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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号