__clone() vs unserialize(serialize())?
With t开发者_运维百科he reference of this question, I got an another solution is use
$obj2 = unserialize(serialize($obj1));
instead of
$obj2 = clone $obj1;
Which one is better to use?
tl;dr version: Use clone
for simple objects and trees, unserialize(serialize())
for complicated graphs of objects.
Longer explanation: Unless $obj1
implements __clone()
, the expression clone $obj1
will return a shallow copy of $obj1
, but sharing the contents of objects pointed to by $obj1
. Even if __clone()
is implemented to perform a deep copy by recursive clone
of members, it will only work safely if the object graph is a tree. If the object graph contains cycles, it will recurse indefinitely and... well... this is Stack Overflow for a reason. :-) If it is a directed acyclic graph but not a tree, any object referenced multiple times will have those multiple references replaced by copies, which may not be what you want.
unserialize(serialize($obj1))
, on the other hand, will deal with cycles in the object graph, but is more expensive in terms of both CPU time and memory.
Sure, that creates a clone, but with incredible overhead and without the ability to actually define any settings or behaviors using the __clone magic method.
I would use the clone keyword and if you're in need of further research see the comments section at http://php.net/manual/en/language.oop5.cloning.php for proofs that cloning doesn't require that a change to one object persists to its clone.
精彩评论