Deep clone
Because cloning, in general, involves copying the entire contents of the object deep ( deep ). That is, it also copies the objects referenced within this object. Eventually one may want until every tree of objects is cloned, if it is possible (referenced objects need to be able to be cloned deeply).
As the way to copy these objects can vary greatly, you have to write the code that will do this. This happens a lot when you secure external resources in the class, such as files and GUI objects, but are not limited to these things. Anything that needs complete data independence needs deep cloning.
Shallow clone
If you do not create this method PHP will clone shallow ( shallow ), that is, it will copy only the object, its members by reference will have only the references copied that will point to the same object that its original object pointed. This may be what you want in some cases, but not at all.
So many people like to lose creating classes. Most programmers do not understand all the implications of creating a class. Usually it works because in general the classes do not do anything sophisticated, or even they were not even necessary in fact. In fact it just does not give a lot of trouble because PHP codes are what I always say, just simple scripts. If they were complex applications indeed many classes would start exploding. In general its use is very contained and deep cloning is not usually necessary. Where they are needed are usually written by programmers who have more notion of how computing functions as a whole.
Clone! = Copy
Note that cloning, even shallow, is different from copying the object, the pure copy only copies the reference of the object, not the object.
Examples
In the example of the question $b
will have an object equal to $a
, but will be another object. They will be completely independent, each with its own life, changing one does not change the other. You cloned and not simply copied. Whether the cloning will be shallow or deep depends on the object type of the $a
variable. As far as I know, ArrayObject
does not clone deeply, at least there's nothing to say this in documentation / a>.
In class X
you are doing this with your member, ensuring that a copy of the member is made and not just the reference.
$x = new X(new Y());
$y = clone $x;
In this case you already know that $x
and $y
will be independent. But most importantly, internally the y
member, accessed by $this
will also be independent in each of the objects, ie this member will be copied too. If I did not have this cloning. Both $x.y
, and $y.y
would point to the same object, and changing in one, would change in the other, they would not be independent. It probably was not what I wanted.
class A {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class B {}
class C extends A {
public function __clone() {
$this->b = clone $this->b;
}
}
$a = new A(new B);
$aa = clone $a;
$b = $a;
$c = new C(new B);
$cc = clone $c;
echo "CÓPIA\n";
var_dump($a === $b); //é igual, ambos apontam para o mesmo objeto
var_dump($a->b === $b->b); //continua igual, é o mesmo objeto, não pode ser diferente
echo "SEM __CLONE\n";
var_dump($a === $aa); //é diferente, copiou o objeto
var_dump($a->b === $aa->b); //é igual, o membro continua sendo o mesmo objeto apontado
echo "COM __CLONE\n";
var_dump($c === $cc); //é diferente, copiou o objeto
var_dump($c->b === $cc->b); //é diferente, copiou o objeto referenciado pelo membro
See working on ideone
The magic method __clone()
is always called by the command clone
of the language, when it is available for that object. If it is not available, cloning will be rare.
Documentation .