gpt4 book ai didi

PHP 克隆 child

转载 作者:行者123 更新时间:2023-12-04 05:19:04 34 4
gpt4 key购买 nike

我有一个对象,它是一个基本的树。我需要对其进行深度复制,并发现自己实现了 __clone 方法。成功的代码是:

function __clone() {
$object = new CustomXML($this->rootElement);
foreach ($this->elements as $key => $element) {
$this->elements[$key] = clone $this->elements[$key];
$object->elements[$key] = $this->elements[$key];
}
$object->attributes = $this->attributes;
$object->value = $this->value;
$object->allowHTML = $this->allowHTML;
$object->endTag = $this->endTag;
$object->styles = $this->styles;
$object->childID = $this->childID;

return $object;
}

我的问题是......为什么我必须使用
$this->elements[$key] = clone $this->elements[$key];
$object->elements[$key] = $this->elements[$key];

为什么我不能只使用
$object->elements[$key] = clone $this->elements[$key];

使用第二个仍然会留下对 child 的引用。为什么是这样? $this->elements 中的值属于同一类。

最佳答案

__clone()在已创建的对象浅拷贝上调用。 See the documentation

PHP 将浅拷贝所有属性并创建一个新对象,而不调用其构造函数(类似于序列化和反序列化)。然后 PHP 调用 __clone()在新对象上,以便您可以根据自己的想法对其进行修改。因为它修改了对象,所以它不应该返回任何东西。

你的代码(如果你总是想要一个深拷贝)应该是这样的:

   function __clone() {
foreach ($this->children as $key => $child) {
$this->children[$key] = clone $this->children[$key];
}
}

不过我 强烈建议您不要这样做 !而不是依赖 clone关键字,添加方法以显式返回克隆对象(例如, DOMNode::cloneNode() 。例如,这将让您控制副本应该是浅的还是深的。如果您只使用 clone,您将无法控制它。

这是一个例子:
interface DeepCopyable
{
/**
* Return a copy of the current object
*
* @param $deep bool If TRUE, return a deep copy
* @return object
*/
public function copy($deep=false);
}

class TreeNode implements DeepCopyable
{
private $I_AM_A_CLONE = false;
protected $children = array();

function __clone() {
$this->I_AM_A_CLONE = true;
}

public function addChild(Copyable $child) {
$this->children[] = $child;
}

public function copy($deep=false) {
$copy = clone $this;
if ($deep) {
foreach ($this->children as $n => $child) {
$copy->children[$n] = $child->copy($deep);
}
}
return $copy;
}
}


$a = new TreeNode();
$a->addChild(new TreeNode());
var_dump($a);
var_dump($a->copy());
var_dump($a->copy(true));

这个例子也说明了 __clone() 的正确使用。 .需要添加克隆魔术方法 当克隆对象的私有(private)或 protected 属性不应与原始 相同时.例如,如果您有一个 id对象上的属性应该是唯一的,您可能希望确保克隆不会具有相同的 ID,并且您永远不想调用代码来控制它。或“脏”标志,或其他任何东西。

关于PHP 克隆 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13883864/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com