elephant-2380009_1280.jpg

Experiment - PHP Object Clone Refs

Published in the topic of Semantic, PHP

Let's prepare your lab coat in case of mind explosion :boom:.

Preparation

Suppose, you find a house described as follow.

Interactive shell

php > class House {
php {   public $rooms = [];
php { }

php > $elpHouse = new House();
php > $elpHouse->bedroom = new stdClass();
php > $elpHouse->bedroom->height = 100;
php > $elpHouse->bedroom->width = 100;

php > print_r($elpHouse);
House Object
(
    [bedroom] => stdClass Object
        (
            [width] => 100
            [height] => 100
        )
)

Then we can ask.

Clone, is it recurse?

Turns out, no!

When object is attached on the property, it's a reference. Sure the reference is copied as value into the cloned parent object. But, the property still refer to the same object.

Here's the proof.

php > $myhouse = clone $elpHouse;
php > print_r($myhouse);
House Object
(
    [bedroom] => stdClass Object
        (
            [width] => 100
            [height] => 100
        )
)

Now we change our our room with additional property.

php > $myhouse->bedroom->lamp = 4;
php > print_r($myhouse);
House Object
(
    [bedroom] => stdClass Object
        (
            [width] => 100
            [height] => 100
            [lamp] => 4
        )
)

Then see if the original elePHPant's room changed (which testify non-recursive nature of clone operation).

php > print_r($elpHouse);
House Object
(
    [bedroom] => stdClass Object
        (
            [width] => 100
            [height] => 100
            [lamp] => 4
        )
)

Clone Affects Array Differently

But, if array is attached in the property, by PHP convention array copy is a new array. Even simple assignment is a copy.

Interactive shell

php > class House {
php {   public $bedrooms = [];
php { }

php > $house = new House;
php > array_push($house->bedrooms, 'firstbedroom');
php > print_r($house);
House Object
(
    [bedrooms] => Array
        (
            [0] => "firstbedroom"
        )
)

When we clone then modify the cloned, it changes the new object property.

php > $sweethouse = clone $house;
php > array_push($sweethouse->bedrooms, 'secondbedroom');
php > print_r($sweethouse);
House Object
(
    [bedrooms] => Array
        (
            [0] => "firstbedroom"
            [1] => "secondbedroom"
        )
)

But the original kept intact.

php > print_r($house);
House Object
(
    [bedrooms] => Array
        (
            [0] => "firstbedroom"
        )
)

This prove that array is cloned by copy, a real content-copy not just array reference copy.


abdillah