Вопрос

Я внедрил простой композитный шаблон с помощью SplobjectStorage, как пример выше:

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

Всякий раз, когда я пытаюсь сериализовать композитный объект, PHP 5.3.2 бросает мне Segmentation FaultОтказ Это происходит только при добавлении любого количества узлов любого типа на объект.

Это оскорбительный код:

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

Хотя это работает:

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

Кроме того, если я реализую композитный шаблон с массивом () вместо SplobjectStorage, все работает хорошо.

Что я делаю не так?

Это было полезно?

Решение

Установив родитель, у вас есть круговая ссылка. PHP попытается сериализовать композит, все его узлы и узлы, в свою очередь, попытаются сериализовать композит .. Boom!

Вы можете использовать магию __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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top