PHP 对象父/子递归

发布于 2024-10-11 01:42:19 字数 282 浏览 8 评论 0原文

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

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

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

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

感谢您的帮助!

I've got a parent-child OO relationship. Parent obejcts has many child objects and every child object knows about it's parent by reference.

The parent can be a child too (basically its a tree).

When i do a var_dump() on the root object it says ["parent"]=>RECURSION many times and the generated description will be really long.

I'm wondering if i do something wrong. If yes, i'm interested in the "best practice".

Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

硬不硬你别怂 2024-10-18 01:42:19

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

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

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

You're not doing anything wrong; you have a parent that has a reference to its children, and each child has a reference back to its parent. When you var_dump() the root object, it iterates over the children to print them, and since each child has a reference to the parent, it walks back up. Because this would normally cause an infinite loop (parent -> child -> parent -> child -> ...), PHP keeps a list of object it has visited already, and when it encounters one, it doesn't try to dump it again but instead prints "RECURSION".

The only thing to look out for with this is that PHP uses reference counting for its garbage collection, and circular constructs like these don't resolve by themselves. As a result, your script will leak memory, which may or may not be a problem. To resolve this, you need to clean up manually: just before the parent object goes out of scope, you need to set all parent pointers to null.

See also: http://bugs.php.net/bug.php?id=33595

败给现实 2024-10-18 01:42:19

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。你没有做错任何事。

点击此处查看其他说明

The var_dump function walks over your object graph recursively and print all accessible data of your objects. Now try to put the below diagram into plain english.

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

If PHP wasn't smart enough to detect this recursion, it would run infinitely. So instead, it recognizes it has dumped that object before and dumps RECURSION. You are not doing anything wrong.

Click here for another explanation

ゝ偶尔ゞ 2024-10-18 01:42:19

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

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

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

The only way you can avoid recursive references is when building a "reversed tree", which is only useful is you want to search from the child to the parent without knowing the siblings. Like:

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

So, from $c you can track up to the root node, being $a, without recursive references.

If you need to go from the root node to the children, then there is no other solution than what you already did, which is correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文