When you assign an object from one variable to another, you do not copy it, but merely assign a handle or reference to it.
<?php class XYZ { public $var = 0; public $abc = 'ABC'; } $a = new XYZ(); $b = $a; $b->var = 2; echo $a->var; # Prints 2, expecting 0 echo $b->var; # Prints 2 # $a and $b point to the same underlying instance of XYZ
However, situations will arise where you’ll actually want to assign a full copy of an existing object to a new variable. This is known as cloning, and is done via the clone
operator.
<?php $a = new XYZ(); $b = clone $a; // $b now is a NEW object with all the member variables set // to the values they had in $a $b->var = 2; echo $a->var; # Prints 0, as expected echo $b->var; # Prints 2
When you clone an object in PHP, the language creates a new instance of the class and assigns copies of the corresponding variables in the original instance to this new object’s member variables by default. However, this is a shallow copy, meaning that if one of those member variables is itself a reference to an object, only that reference is copied.
__clone function
If the default behavior for cloning is not sufficient for your needs, you can implement the __clone
function in your class, which PHP calls after it has performed the shallow copy of the member variables.
Remember example in the Static Variables and Methods tutorial, we used a static variable to count the number of instances of a class that have been created:
class User { private static $x = 0; public function __construct () { self::$x++; echo 'Instances created: '. self::$x .'<br>'; } } $a = new User(); # Prints: Instances created: 1 $b = clone $a; # Prints nothing
In the above code, the increment was performed in the constructor and when you clone an object the User class does not count the cloned object. To solve this, we use __clone
method in the User class:
<?php class User { private static $x = 0; public function __construct () { self::$x++; echo 'Instances created: '. self::$x .'<br>'; } function __clone() { self::$x++; echo 'Instances created: '. self::$x .'<br>'; } } $a = new User(); # Instances created: 1 $b = clone $a; # Instances created: 2
Now, whenever the object is cloned, the __clone
method is called and the cloned instance is also counted.
The __clone()
method does not override the cloning process, it just allows you to amend the wrongdoing, where you might not normally be satisfied with the outcome.
PHP OOP Tutorials: