Pregunta

I han implementado un patrón Composite simple usando SplObjectStorage, como el ejemplo anterior:

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

Siempre que trato de serializar un objeto compuesto, PHP 5.3.2 me lanza una Segmentation Fault. Esto sólo ocurre cuando agrego cualquier número de nodos de cualquier tipo al objeto.

Este es el código erróneo:

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

A pesar de que este funciona:

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

Además, si puedo implementar el patrón Composite con array () en lugar de SplObjectStorage, todas las carreras bien también.

Lo que estoy haciendo mal?

¿Fue útil?

Solución

Al establecer el padre, usted tiene una referencia circular. PHP tratará de serializar el compuesto, todo ello de nodos y los nodos a su vez tratar de serializar el compuesto .. bum!

Se puede usar la magia __sleep y __wakeup() métodos a eliminar (o lo que sea a la) la referencia de los padres cuando se serializa.

EDIT:

A ver si la adición de estos arreglos a Composite el tema:

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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top