【问题标题】:PHP object parent/child recursionPHP对象父/子递归
【发布时间】:2011-06-05 08:39:29
【问题描述】:

我有 父子 OO 关系。父对象有许多子对象,每个子对象都通过引用知道它的父对象。

父母也可以是孩子(基本上是一棵树)。

当我在根对象上执行 var_dump() 时,它会多次显示 ["parent"]=>RECURSION 并生成描述会很长。

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

感谢您的帮助!

【问题讨论】:

  • 一些代码会很好!
  • 听起来您的图表中有一个循环(父母也是其后代之一的孩子),但如果没有看到代码或示例数据,很难确定。
  • 只要您确定递归不是太深,就可以了。否则你可能会遇到问题,例如用 json 编码对象。
  • google.com/search?q=RECURSION 的经典案例(很诱人)
  • 是的,我知道“递归”是什么,我的问题是关于它是否是 PHP 中的问题(如果是,那么如何处理它)或者它只会弄乱 var_dump 的响应。

标签: php parent-child relationship


【解决方案1】:

你没有做错任何事;您有一个对其子项的引用的父项,并且每个子项都有对其父项的引用。当您var_dump() 根对象时,它会遍历子对象以打印它们,并且由于每个子对象都有对父对象的引用,因此它会向上走。因为这通常会导致无限循环(父 -> 子 -> 父 -> 子 -> ...),所以 PHP 会保留一个它已经访问过的对象的列表,当它遇到一个时,它不会尝试转储再次打印,而是打印“RECURSION”。

唯一需要注意的是,PHP 使用引用计数来进行垃圾收集,而像这样的循环结构不能自行解决。结果,您的脚本将泄漏内存,这可能是也可能不是问题。要解决这个问题,您需要手动清理:就在父对象超出范围之前,您需要将所有父指针设置为 null。

另请参阅:http://bugs.php.net/bug.php?id=33595

【讨论】:

【解决方案2】:

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

【讨论】:

    【解决方案3】:

    您可以避免递归引用的唯一方法是构建“反向树”,这仅在您想在不知道兄弟姐妹的情况下从子节点搜索到父节点时才有用。喜欢:

    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,无需递归引用。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-30
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多