22

I have a class a and instantiated it using new

$obja = new a;

I know the difference between the below two lines

$obja2 = $ojba;
$obja2 = clone $obja;

But even if you declare or not declare __clone in the class a the first line $obja2 refer to $obja memory space and second line creates a copy of the $obja. Till here it is clear to me.

Then why php is having a magic method __clone? Is it only for executing a set of codes which is written inside __clone while we use $obja2 = clone $obja;

Somebody please help to get a better idea of it.

3
  • It exists to allow you to clone any object instances held within the object if you need to - by default the pointers would be copied but the new object would effectively have the same instances of the child objects. Commented Dec 20, 2012 at 11:11
  • @DaveRandom : Can u explain a bit more simpler :) may be a link or anything that better explains this. i have already done my googling Commented Dec 20, 2012 at 11:16
  • 2
    Consider an object of class A with a property $innerB, which contains an instance of the class B. When you clone the instance of A, the new object will have the same instance of B. By using clone, you could do $this->innerB = clone $this->innerB; - so you get a new instance of B for the new object as well. Consider this vs this. Commented Dec 20, 2012 at 11:23

2 Answers 2

28
void __clone ( void )

Once the cloning is complete, if a __clone() method is defined, then the newly created object's __clone() method will be called, to allow any necessary properties that need to be changed.

http://php.net/manual/en/language.oop5.cloning.php#object.clone

So yes, it's a callback after the clone operation has finished. Nothing more, nothing less.

Sign up to request clarification or add additional context in comments.

4 Comments

so what is the problems that it creates if i don't write __clone() in a class?
That depends on what you want/need to do. Is the default behavior of a PHP clone operation sufficient for what you want to do when cloning objects? Then there's no need. If you need to do more things to make a "complete" clone, add that code in the __clone callback method. Lame example: if each of your objects needs to have a unique ID ($this->id variable or something along those lines), you'll need to generate a new ID after a clone to avoid having two objects with the same ID.
Other example: clone creates a "shallow copy". This means, that only the object itself gets cloned, but not its associations. So if this object of A has associations to other objects, which must be unique between difference instances A, you must clone the associations within __clone() too: $this->otherObject = clone $this->otherObject;
Note that ONLY __clone called during clone(A) is the A::__clone() - if A has an inner property B $b, B::__clone() will not be called even though implemented!
27

The clone keyword in PHP represents a shallow copy.

In order to achieve a deep copy, you need to implement the magic method __clone

If you clone an object that has a member which is an object of another class with the simple clone keyword, you would be keeping the same reference to that second object.

That's where the deep copy comes in handy, with something like this:

public function __clone()
{
    $this->someOtherObject = clone $this->someOtherObject;
}

With that, you guarantee the clone will be deep, meaning it will clone the member objects as well, instead of just keeping the original reference to them.

1 Comment

I would like to note, that this does NOT guarantee the clone to be deep if the referenced object has also referenced objects - you may think "oh I have only a data class" - but think again, maybe it has a DateTime or some sort of Collection property or something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.