Search code examples
phpobjectclone

PHP Cloneable Object


I went through this example on the PHP Manual.

<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
    }

    public function __clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
        // Force a copy of this->object, otherwise
        // it will point to same object.
        $this->object1 = clone $this->object1;
        $this->object2 = clone $this->object2;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("Original Object:\n");
print_r($obj);

print("Cloned Object:\n");
print_r($obj2);

?>

When i execute this $obj2 = clone $obj; can someone explain me what happens actually ? Will this call MyCloneable Class's function __clone() or SubObject Class's public function __clone() ?

Step by step explanation would be more helpful. Thanks.


Solution

  • __clone function handles the clone keyword. Using

    $obj2 = clone $obj;
    

    could be represented as

    $obj2 = $obj::__clone();
    

    But that's obvious to you.

    clone ... calls the __clone method of the MyCloneable class. It has nothing to do with the SubObject class. object1 and object2 are only properties of the $obj object which is of class MyCloneable.

    Of course, when you call the clone, the object1 and object2 properties will be cloned but they'll still be the object's properties. The $obj2 will be of class MyCloneable.

    Does my answer satisfy your needs?

    EDIT:

    clone keywords inside the MyCloneable::__clone() method are creating clones of the $object1 and $object2 properties. In practice, it gives nothing because you're assigning the clones to the makers of these clones.
    What happens in MyCloneable::__clone() - it is calling SubObject::__clone() method which in fact does this:

    $this->instance = ++self::$instances;
    

    Notice that instances property is static so every time you create a new or clone an existing object, the instances increments.