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
Here is my best practice on an array of objects and cloning. Usually it is a good idea, to have a Collection class for each class of objects (or interface), which are used in an array. With the magic function __clone
cloning becomes a formalized routine:
class Collection extends ArrayObject
{
public function __clone()
{
foreach ($this as $key => $property) {
$this[$key] = clone $property;
}
}
}
To clone your array, use it as Collection and then clone it:
$arrayObject = new Collection($myArray);
$clonedArrayObject = clone $arrayObject;
One step further, you should add a clone method to your class and each sub-class, too. This is important for deep cloning, or you might have unintended side effects:
class MyClass
{
public function __clone()
{
$this->propertyContainingObject = clone $this->propertyContainingObject;
}
}
An important note on using ArrayObject is, that you cannot use is_array()
any longer. So be aware of this on refactoring your code.
or also
$nuarr = json_decode(json_encode($array));
but it is expensive, I prefer Sebastien version (array_map)
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);
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.
$array = array_merge(array(), $myArray);
$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', )