Deep clone
Because cloning, in general, involves copying the entire content of the object in a profound way (deep). That is, it also copies the referenced objects within that object. Eventually one may want until every object tree is cloned, if possible (the referenced objects need to be able to be cloned deeply).
Since 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 is not limited to these things. Anything that needs full data independence needs deep cloning.
Shallow clone
If you do not create this method PHP will clone shallowly (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.
Then a lot of people get lost creating classes. Most programmers don’t understand all the implications of creating a class. It usually works because in general the classes do nothing sophisticated, or even they were not even necessary at all. Actually just doesn’t give a lot of trouble because PHP codes are what I always say, just scripts simple. If they were complex applications in fact many classes would start to explode. 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 works as a whole.
Clone != Copy
Note that cloning, even shallow, is different from copying the object, the pure copy only copies the object reference, not the object.
Examples
In the example of the question $b
will have an object just like $a
, but it will be another object. They will be completely independent, each with its own life, changing one does not change the other. You cloned and did not simply copy. Whether cloning will be shallow or deep depends on the type of the variable object $a
. As far as I know ArrayObject
does not clone deeply, at least has nothing to say this in documentation.
In class X
is doing this with your member, ensuring that a copy of the member is made and not only the reference.
$x = new X(new Y());
$y = clone $x;
Then you know that $x
and $y
shall be independent. But the most important thing is that the y
, accessed by $this
will also be independent in each of the objects, ie this member will be copied as well. If not had this cloning. Both $x.y
, how much $y.y
would point to the same object, and changing into one, would change into the other, they would not be independent. Probably not what you 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
Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.
The magical method __clone()
is always called by the command clone
language, when the method is available to that object, if it is not available, the cloning will be shallow.
Documentation.
But he really is a magician?
– Bacco
Yes, he’s Magical, Magical
– Wallace Maxters
http://i.stack.Imgur.com/Ykzbv.jpg
– Bacco
It also serves to deprive your class of being cloned. When you make the method 'private'. It is widely used in standard Singleton Pattern design.
– Ivan Ferrer
@Ivanferrer good observation, that’s good.
– Wallace Maxters
http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=205960&type=card
– MagicHat
This is a method I’ve never understood what it’s really for
– Papa Charlie