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 $b
和 print_r()
试图显示 $b
的 parent,它指向 $a
)
我对 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 $b
和 print_r()
试图显示 $b
的 parent,它指向 $a
)