脚本宝典收集整理的这篇文章主要介绍了在PHP中克隆父子树,从子节点开始,避免无休止的递归,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
[Root] -- [Element1] START CLONE -- [Element3] -- [Element4] -- [Element2] -- [Element5]
所以我想做的是克隆整个树,通过调用$new = clone $element1;
__clone()方法声明还必须克隆每个子节点,并且,如果出现图示的情况*,则还必须克隆父节点.
* Root在Element1中显式设置为父级,因此系统可以识别这种情况并对其执行某些操作.
问题是,从Element1开始克隆操作时,还必须克隆Root. Root的克隆过程规定必须克隆所有子元素,因此再次调用Element1的克隆操作,然后重复相同的克隆过程,产生无限循环.
此外,Root不会包含Element1的第一个克隆,但它会生成自己的克隆以作为子元素添加.然后,Element1将Root作为其父级,但Root将不具有与子级相同的Element1.
我希望我能以清晰的方式提出问题,有人可以帮我找到解决方案.
编辑:
最终解决方案
/** * The $replace and $wITh arguments allow a custom @R_771_1419@ PRocedure. Instead of * being cloned,the original child $replace will be replaced by $with. */ public function duplicate($replace = null,$with = null) { // Basic @R_771_1419@ $clone = clone $this; // If parent is set if(isset($this->parent)) { // Clone parent,replace this element by its clone $parentClone = $this->parent->duplicate($this,$clone); $clone->parent = $parentClone; } // Remove all children in the clone $clone->clear(); // Add cloned children From original to clone foreach($this->getChildren() as $child) { if($child === $replace) // If @R_771_1419@ was initiated from this child,replace with given clone $childClone = $with; else // Else duplicate child normally $childClone = $child->duplicate(); // Add cloned child to this clone $clone->add($childClone); } return $clone; }
[Root] -- [Element1] START CLONE -- [Element3]
然后你做的不同,我认为你有三个操作
>公共克隆方法.
>自我克隆操作,返回带子节点的克隆,但不返回父节点.
>单克隆操作,返回没有子节点的克隆.
类之外的代码使用公共克隆方法.但是__clone()方法不能使用该方法,否则会遇到您所描述的循环循环问题.所以__clone()实现必须使用其他方法.
将cloneSelf和cloneSingle方法添加到您的类中,使它们受到保护,因此继承的类可以调用它们,但它们不公开.
然后在__clone()实现中使用它们:
public function clone() { // clone the parent $parent = $this->getParent(); $parentClone = $parent->cloneSingle(); // clone all children of parent which includes $this $selfclone = NULL; foreach($parent->getChildren() as $child) { $childClone = $child->cloneSelf(); if (!$selfClone && $child === $this) $selfClone = $childClone; $parentClone->addChild($childClone); } assert('$selfClone'); return $selfClone; } public function __clone() { $message = 'Clone operator is not Allowed,use clone() method instead.'; throw new BadMethodCallException($message); }
这些方法还可以帮助您在没有父级的情况下进行克隆.
以上是脚本宝典为你收集整理的在PHP中克隆父子树,从子节点开始,避免无休止的递归全部内容,希望文章能够帮你解决在PHP中克隆父子树,从子节点开始,避免无休止的递归所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。