OOP 最大函数嵌套层级

OOP maximum function nesting level

我对 OOP 有一种奇怪的看法

我的class很简单

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 的错误,我知道为什么,但是我应该如何更改代码?现在的方式是有道理的,但如果我删除任何函数调用,它就不会像它应该的那样工作。

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

如果您希望您的代码工作,以便调用 setParent() 调用 addChild() 强制执行 [=54] 中的属性关系=]both objects,您可以通过在 addChild() 中添加一个 if () 条件来解决您当前遇到的无限循环,仅当object 的 parent 还不是当前的 object ($this)。

同样,您需要检查要添加为 addChild() 中的 child 的 object 是否尚未添加到 parent 的 $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
)

现在,使用 inverse 操作,从 $a$b 开始,然后将 $b 作为 child 添加到$a 而不是添加 $a 作为 $b 的 parent:

$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() 输出中的 "RECURSION" :这并不表示方法调用是递归的,只是 object 引用之间存在递归关系,这就是你想要的。$a 有一个 child $bprint_r() 试图显示 $b 的 parent,它指向 $a)