2012-05-02 61 views
1

我已到处寻找,似乎无法找到答案。我想知道的是,如果在PHP中使用递归对象是安全的还是很好的做法。要创建一个对象作为另一个对象,包含与该包含对象的引用的属性的属性...使用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(); 
    ?> 

我注意到我在使用某些函数时遇到了问题,例如array_multisort(特别是“PHP致命错误:嵌套级别太深 - 递归依赖性?”),当尝试对对象数组进行排序时,以及当我使用var_dump时,它显示了一些属性作为递归...

任何帮助是明智的iated

+0

只要您知道自己在做什么,并且知道如何解决该问题,它就很安全。很显然,如果你使用的是array_multisort,你并不是围绕着循环引用。 – gcochard

+0

我想这就是我有点困惑......关于如何处理尝试对包含循环引用的对象数组进行排序的任何想法? –

+0

简单。假设您不需要一路下来,只需对顶层数组进行排序即可。你不需要递归排序;只需使用像'usort'这样的比较函数来正确比较两个对象。 – cHao

回答

4

在PHP 5.3之前,这可能会导致一个问题。 PHP用于执行引用计数,并使用循环引用来防止对象被GCed。

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

0

请注意,bar->database->any_method()将无法​​正常工作,因为database是私人的。

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

如果你做一个Uservar_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注意到递归。

我也得问问为什么你会这样做。

+0

是啊,我意识到我提出了私人类型,我的意思是它是公开的....无论如何,我试图从我的用户方法分离数据库方法,以便每次创建一个用户对象,它有一个数据库对象包含所有方法将处理检索该特定用户的数据 –