How to clone an array of objects in PHP?

Viewed 86882

I have an array of objects. I know that objects get assigned by "reference" and arrays by "value". But when I assign the array, each element of the array is referencing the object, so when I modify an object in either array the changes are reflected in the other.

Is there a simple way to clone an array, or must I loop through it to clone each object?

16 Answers

A pure PHP 7.4 >= solution:

$cloned = array_map(fn ($o) => clone $o, $original);

For PHP 5 and above one can use ArrayObject cunstructur to clone an array like the following:

$myArray = array(1, 2, 3);
$clonedArray = new ArrayObject($myArray);

If you have multidimensional array or array composed of both objects and other values you can use this method:

$cloned = Arr::clone($array);

from that library.

Just include this function in all of your classes. This will do a deep clone of all objects in case if you have arrays of objects within the object itself. It will trigger all of the __clone() functions in these classes:

/**
 * Clone the object and its properties
 */
public function __clone()
{
    foreach ($this as $key => $property)
    {
        if(is_array($property))
        {
            foreach ($property as $i => $o)
            {
                if(is_object($o)) $this->$key[$i] = clone $o;
                else $this->$key[$i] = $o;
            }
        }
        else if(is_object($property)) $this->$key = clone $property;
        else $this->$key = $property;
    }
}
$a = ['a'=>'A','b'=>'B','c'=>'C'];
$b = $a+[];
$a['a'] = 'AA'; // modifying array $a
var_export($a);
var_export($b); 

Result:

array ( 'a' => 'AA', 'b' => 'B', 'c' => 'C', )
array ( 'a' => 'A', 'b' => 'B', 'c' => 'C', )

i prefer recursive way:

function deepClone(mixed $object): mixed
{
    switch (gettype($object)) {
        case 'object':
            return clone $object;

        case 'array':
            $ret = [];
            foreach ($object as $key => $item) {
                $ret[$key] = deepClone($item);
            }
            return $ret;

        default:
            return $object;
    }
}

deepClone($array);
Related