我对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的错误,我知道为什么,但是我应该如何更改代码呢?它现在的方式是有道理的,但如果我删除任何函数调用它将无法正常工作。
答案 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}})