答案 0 :(得分:10)
tl; dr version:对于简单的对象和树使用clone
,对于复杂的对象图使用unserialize(serialize())
。
更长的解释:除非$obj1
实施__clone()
,否则表达式clone $obj1
将返回$obj1
的浅表副本,但共享内容$obj1
指向的对象。即使__clone()
被实现为通过递归clone
成员执行深层复制,它也只能在对象图是树的情况下安全地工作。如果对象图包含循环,它将无限递归并且......好吧......这是Stack Overflow的原因。 :-)如果它是有向非循环图而不是树,任何多次引用的对象都会将这些多个引用替换为副本,这可能不是你想要的。
unserialize(serialize($obj1))
将处理对象图中的循环,但在CPU时间和内存方面都更加昂贵。
答案 1 :(得分:3)
当然,这会创建一个克隆,但具有令人难以置信的开销,并且无法使用__clone魔术方法实际定义任何设置或行为。
我会使用clone关键字,如果您需要进一步研究,请参阅http://php.net/manual/en/language.oop5.cloning.php上的评论部分,以获取克隆不要求对一个对象的更改持续存在于其克隆中的证据。