w3school - php copy array without reference




How to clone an array of objects in PHP? (8)

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?


As suggested by AndreKR, using array_map() is the best way to go if you already know that your array contains objects:

$clone = array_map(function ($object) { return clone $object; }, $array);

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);

I opted for clone as well. Cloning an array does not work (you could consider some arrayaccess implementation to do so for you), so as for the array clone with array_map:

class foo {
    public $store;
    public function __construct($store) {$this->store=$store;}
}

$f = new foo('moo');
$a = array($f);

$b = array_map(function($o) {return clone $o;}, $a);

$b[0]->store='bar';    
var_dump($a, $b);

Array clone with serialize and unserialize

If your objects support serialisation, you can even sort of deep shallow copy/clone with a tour into their sleeping state and back:

$f = new foo('moo');
$a = array($f);

$b = unserialize(serialize($a));

$b[0]->store='bar';
var_dump($a, $b);

However, that can be a bit adventurous.


I've done it like this:

function array_clone($array) {
    array_walk_recursive($array, function(&$value) {
        if(is_object($value)) {
            $value = clone $value;
        }
    });
    return $array;
}

The function arg copies the array without cloning the objects, then each nested object is cloned. So it won't work if the algorithm is not used inside a function.

Note this function clone the array recursively. You can use array_walk instead of array_walk_recursive if you do not want this to happen.


References to the same objects already get copied when you copy the array. But it sounds like you want to shallow-copy deep-copy the objects being referenced in the first array when you create the second array, so you get two arrays of distinct but similar objects.

The most intuitive way I can come up with right now is a loop; there may be simpler or more elegant solutions out there:

$new = array();

foreach ($old as $k => $v) {
    $new[$k] = clone $v;
}

You need to clone objects to avoid having references to the same object.

function array_copy($arr) {
    $newArray = array();
    foreach($arr as $key => $value) {
        if(is_array($value)) $newArray[$key] = array_copy($value);
        else if(is_object($value)) $newArray[$key] = clone $value;
        else $newArray[$key] = $value;
    }
    return $newArray;
}

or also

$nuarr = json_decode(json_encode($array));

but it is expensive, I prefer Sebastien version (array_map)


$array = array_merge(array(), $myArray);




clone