OOP最大函数嵌套级别

时间:2015-03-16 23:02:47

标签: php class oop

我对OOP有一个奇怪的情况

我的课很简单

class Thing{

  private
    $children = array(),
    $parent;


  public function addChild(self $thing){
    $this->children[] = $thing;
    $thing->setParent($this);
  }

  public function setParent(self $thing){
    $this->parent = $thing;
    $thing->addChild($this);
  }

}


$a = new Thing();
$b = new Thing();

$b->setParent($a);

如果我尝试使用这些函数,我会得到最大函数嵌套级别为100的错误,我知道为什么,但是我应该如何更改代码呢?它现在的方式是有道理的,但如果我删除任何函数调用它将无法正常工作。

1 个答案:

答案 0 :(得分:2)

正如评论中所述,您的代码会在setParent()addChild()之间创建一个无限循环,其中对setParent()的调用也会隐式调用setChild(),而setParent()会调用setParent()再次addChild()

如果您希望代码能够正常工作,以便调用if () 调用addChild()来强制执行中属性的关系对象,您可以通过在setParent()内添加$this条件来解决当前遇到的无限循环,仅当对象的父级不是当前对象时才调用addChild() $children)。

同样,您需要检查in_array()中要添加为儿童的对象是否尚未使用class Thing{ private $children = array(), $parent; // A name property just to see the results public $name; public function addChild(self $thing){ $this->children[] = $thing; // Only set this object to the passed-in $thing object's // $parent property if it has not already been set: if ($thing->parent !== $this) { $thing->setParent($this); } } public function setParent(self $thing){ $this->parent = $thing; // Only add the child via addChild() if it is not // already in the array if (!in_array($this, $thing->children)) { $thing->addChild($this); } } } $a = new Thing(); $a->name = "THING A"; $b = new Thing(); $b->name = "THING B"; // Specify $a as the parent of $b $b->setParent($a); echo "\$a properties:\n"; print_r($a); echo "\$b properties:\n"; print_r($b); 添加到父$a properties: Thing Object ( [children:Thing:private] => Array ( [0] => Thing Object ( [children:Thing:private] => Array ( ) [parent:Thing:private] => Thing Object *RECURSION* [name] => THING B ) ) [parent:Thing:private] => [name] => THING A ) $b properties: Thing Object ( [children:Thing:private] => Array ( ) [parent:Thing:private] => Thing Object ( [children:Thing:private] => Array ( [0] => Thing Object *RECURSION* ) [parent:Thing:private] => [name] => THING A ) [name] => THING B ) 数组中。< / p>

$a

以上的输出是:

$b

现在,使用反向操作,从$b$a开始,然后将$a作为子项添加到$b,而不是添加{ {1}}作为$a = new Thing(); $a->name = "THING A"; $b = new Thing(); $b->name = "THING B"; // Add $b as a child of $a $a->addChild($b); 的父级:

$a properties:
Thing Object
(
    [children:Thing:private] => Array
        (
            [0] => Thing Object
                (
                    [children:Thing:private] => Array
                        (
                        )

                    [parent:Thing:private] => Thing Object
 *RECURSION*
                    [name] => THING B
                )

        )

    [parent:Thing:private] => 
    [name] => THING A
)
$b properties:
Thing Object
(
    [children:Thing:private] => Array
        (
        )

    [parent:Thing:private] => Thing Object
        (
            [children:Thing:private] => Array
                (
                    [0] => Thing Object
 *RECURSION*
                )

            [parent:Thing:private] => 
            [name] => THING A
        )

    [name] => THING B
)

产生相同的输出:

print_r()

(注意&#34; RECURSION&#34;在$a输出中:这并不表示方法调用是递归行为,只是在对象引用之间存在递归关系,这就是你想要。$b有一个孩子print_r()$b尝试显示$a的父母,其指向{{1}})