Frage

Ich habe ein einfaches Composite-Muster mit SplObjectStorage implementiert, wie das obigen Beispiel:

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

Jedes Mal, wenn ich versuche, ein Composite-Objekt zu serialisiert, PHP 5.3.2 wirft mir einen Segmentation Fault. Dies geschieht nur, wenn ich auf das Objekt eine beliebige Anzahl von Knoten eines beliebigen Typs hinzuzufügen.

Dies ist der säumige Code:

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

Obwohl diese funktionieren:

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

Auch wenn ich das Composite-Muster mit Array implementieren () anstelle von SplObjectStorage, alle Läufe auch ok.

Was mache ich falsch?

War es hilfreich?

Lösung

Durch die übergeordnete Einstellung haben Sie einen zirkulären Verweis. PHP wird versuchen, den Verbund zu serialisiert, alle seine Knoten und die Knoten wiederum wird versuchen, den Verbund .. Boom serialisiert werden!

Sie können die Magie benutzen __sleep und __wakeup() Methoden entfernen (oder tun, was zu dem) der Mutter Referenz, wenn die Serialisierung.

EDIT:

Sehen Sie, wenn das Hinzufügen dieser Composite beheben das Problem:

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top