2011-01-07 2 views
6

У меня есть отношение OO от родителя-ребенка. Родительские obejcts имеют много дочерних объектов, и каждый дочерний объект знает о его родителе по ссылке.PHP-объект родительский/дочерний рекурсия

Родителем может быть ребенок (в основном его дерево).

Когда я делаю var_dump() корневого объекта он говорит [ «родитель»] =>рекурсии много раз и сгенерированного описание будет очень долго.

Мне интересно, если я что-то сделаю неправильно. Если да, меня интересует «лучшая практика».

Спасибо за помощь!

+0

Некоторый код будет приятным! –

+1

Похоже, у вас есть цикл в вашем графике (родитель, который также является дочерним из одного из его делений), но без просмотра кода или выборочных данных трудно сказать наверняка. – FrustratedWithFormsDesigner

+0

до тех пор, пока вы уверены, что рекурсия не слишком глубокая, все в порядке. В противном случае могут возникнуть проблемы, например. кодирование объекта с помощью json. – usoban

ответ

12

Вы не делаете ничего плохого; у вас есть родитель, у которого есть ссылка на его детей, и у каждого ребенка есть ссылка на родителя. Когда вы используете var_dump() корневой объект, он выполняет итерацию над детьми, чтобы напечатать их, а так как каждый ребенок имеет ссылку на родителя, он возвращается обратно. Поскольку это обычно вызывает бесконечный цикл (parent -> child -> parent -> child -> ...), PHP хранит список объектов, которые он уже посетил, и когда он встречает один, он не пытается сбросить он снова, но вместо этого печатает «RECURSION».

Единственное, на что нужно обратить внимание, заключается в том, что PHP использует подсчет ссылок для своей коллекции мусора, а круговые конструкции, подобные этим, сами не разрешают. В результате ваш скрипт будет утечка памяти, что может быть или не быть проблемой. Чтобы решить эту проблему, вам нужно очистить ее вручную: перед тем как родительский объект выходит из области видимости, вам нужно установить все родительские указатели равными нулю.

Смотрите также: http://bugs.php.net/bug.php?id=33595

+0

Утечка памяти, по-видимому, исправлена ​​с PHP 5.3: (см. Последние 2 комментария по адресу: https://bugs.php.net/bug.php?id=33595) –

6

var_dump функция подходит над графиком объекта рекурсивно и напечатать все доступные данные объектов. Теперь попробуйте поместить приведенную ниже диаграмму в простой английский.

 has    var_dump: 
Parent ----> Child   "The Parent object has a child object" 
^    |    "That Child object has a Parent Object" 
|______________| has    "That Parent object …" 

Если PHP не был достаточно умен, чтобы обнаружить эту рекурсию, он будет работать бесконечно. Поэтому вместо этого он распознает, что он сбрасывал этот объект раньше и сбрасывает RECURSION. Вы ничего не делаете неправильно.

Click here for another explanation

0

Единственный способ избежать рекурсивных ссылок при создании «обращенного дерева», которое только полезно, что вы хотите, чтобы найти ребенок к родителю, не зная, брат и сестра. Как:

class Foo { 
    protected $parent; 

    public function __construct(Foo $parent = null) { 
     $this->parent = $parent; 
    } 

    public function getParent() { 
     return $this->parent; 
    } 
} 

$a = new Foo; 
$b = new Foo($a); 
$c = new Foo($b); 

Итак, из $c вы можете отслеживать до корневого узла, будучи $a, без рекурсивных ссылок.

Если вам нужно перейти от корневого узла к детям, то нет другого решения, кроме того, что вы уже сделали, что правильно.