Errore serializzazione di un albero di oggetti con SplObjectStorage
-
01-10-2019 - |
Domanda
Ho implementato un semplice composite utilizzando SplObjectStorage, come nell'esempio precedente:
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);
}
}
Ogni volta che provo per serializzare un oggetto composito, PHP 5.3.2 mi butta un Segmentation Fault
.
Ciò accade solo quando aggiungo un numero qualsiasi di nodi di qualsiasi tipo per l'oggetto.
Questo è il codice incriminato:
$node = new Node;
$composite = new Composite;
$composite->add($node);
echo serialize($composite);
Anche se questo funziona:
$node = new Node;
$composite = new Composite;
echo serialize($composite);
Inoltre, se a implementare il modello composito con array () al posto di SplObjectStorage, tutte le piste troppo male.
Quello che sto facendo di sbagliato?
Soluzione
Con l'impostazione della Capogruppo, si ha un riferimento circolare. PHP cercherà di serializzare il composito, tutto quanto di nodi e nodi a loro volta cercheranno di serializzare l'asta .. composito!
È possibile utilizzare la magia __sleep
e __wakeup()
metodi per rimuovere (o fare qualsiasi cosa per il) il genitore di riferimento durante la serializzazione.
Modifica
Vedere se l'aggiunta di questi per correzioni Composite
il problema:
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;
}