Search code examples
phpclonepass-by-reference

passing by reference in __clone


In my __clone method I'm assigning, by reference, one variable to the other. What I'd expect to happen, after cloning, is that when I change this variable for one object it gets changed in the other object. But that doesn't appear to be happening.

My code:

class a {
    var $a;

    function a($var = NULL) {
        if (isset($var)) {
            $this->a = $var;
        }
    }

    function __clone() {
        $temp = new a();
        $temp->a = &$this->a;
        return $temp;
    }
}

$a = new a('test');
$b = clone $a;
$b->a = 'zzz';

echo $a->a;
echo "\r\n";
echo $b->a;

The output is this:

test
zzz

I'd expect it to be this:

zzz
zzz

Solution

  • Before your __clone method is called, PHP already copied all the properties by value. After PHP finished cloning your object, your method is called. Therefore any property that you access in that method already is a value copy. The documentation states:

    When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references.

    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.

    You can find this in the second paragraph of this page.

    Although this is not a very beautiful workaround, you could rename your __clone method. You could then use that method to clone your object, although this of course is not an actual clone anymore since it does not use the interface for cloning.