2011-01-07 91 views
6

我有一个亲子关系。父对象具有许多子对象,并且每个子对象通过引用知道它的父对象。PHP对象父/子递归

父母也可以是孩子(基本上它的树)。

在i根对象上做一个的var_dump()它说[“父”] =>递推多次并且将所生成的描述将是很长的。

我想知道如果我做错了什么。如果是的话,我对“最佳实践”感兴趣。

感谢您的帮助!

+0

一些代码会很好! – 2011-01-07 15:41:04

+1

听起来像你在图中有一个循环(父母也是其后代之一的孩子),但是没有看到代码或样本数据,很难肯定地说。 – FrustratedWithFormsDesigner 2011-01-07 15:41:19

回答

12

你没有做错任何事;你有一个家长参考其子女,每个孩子都有一个参考回到其父母。当你对根对象进行迭代时,它遍历子对象来打印它们,并且由于每个子对象都有对父对象的引用,所以它会返回。因为这通常会导致一个无限循环(父 - >子 - >父 - >子 - > ...),PHP保留已经访问的对象的列表,并且当它遇到一个时,它不会尝试转储它再次,但是打印“RECURSION”。

唯一需要注意的是PHP使用引用计数来处理垃圾回收,像这样的循环结构不能自行解决。因此,您的脚本会泄漏内存,这可能会也可能不会成为问题。为了解决这个问题,你需要手动清理:在父对象超出作用域之前,你需要将所有父指针设置为空。

参见:http://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,没有递归引用。

如果您需要从根节点转到子节点,那么没有其他解决方案比您已经做了,这是正确的。