使用 PHP 对象设置递归属性是否安全


Is it safe to set recursive properties with PHP object?

我到处找了,似乎找不到答案。我想知道的是,在 PHP 中使用递归对象是否安全或良好做法。 要将一个对象创建为另一个对象的属性,该对象包含一个引用包含对象的属性...

<?php
    class User
    {
        public $database;
        public function __construct() {
            $this->database = new Database($this);
        }
    }
    Class Database
    {
        private $user;
        public function __construct(User $user) {
            $this->user = $user;
        }
        public function doSomethingForUser() {
            // Call db or get info for this user
        }
    }

然后按如下方式使用它...

    <?php
        $bar = new User();
        $bar->database->doSomethingForUser();
    ?>

我只是注意到我在尝试对var_dump对象数组进行排序时遇到了使用某些函数的问题,例如 array_multisort(特别是"PHP 致命错误:嵌套级别太深 - 递归依赖?

任何帮助不胜感激

在 PHP 5.3 之前,这可能会导致问题。 PHP 用于执行引用计数,循环引用用于防止对象被 GC 处理。

现在 5.3 实现了一个不错的垃圾收集器,这不是一个大问题。 但是,将这些对象传递给遍历对象图的任何函数仍可能导致无限递归,如果该函数不知道这种可能性并准备处理它。 (我认为var_dump处理递归的方式不错,但递归地对此类对象进行排序可能会导致各种麻烦。

请注意,bar->database->any_method()不起作用,因为database是私有的。

当你在PHP中创建对对象的递归引用时,它实际上非常好 - 它只是使用现有的引用,显然不会创建更多的内存。 在这种情况下,您不会创建非确定性的递归级别 - 它只是一组对象,因此除非您创建大量这些对象(并且可能出于其他原因),否则不太可能溢出。

如果你对User执行var_dump,你将看到:

object(User)#1 (1) {
  ["database:private"]=>
  object(Database)#2 (1) {
    ["user:private"]=>
    object(User)#1 (1) {
      ["database:private"]=>
      object(Database)#2 (1) {
        ["user:private"]=>
        *RECURSION*
      }
    }
  }
}

。所以PHP注意到了递归。

我还要问你为什么在这种情况下这样做。