Skip to content
Advertisement

PHP: Storing arrays within an array seems to be creating copies

This is such a basic question, but I’m unable to find a clear answer anywhere. As I have understood it, storing an object in an array should store a reference, not a copy… so any changes you make to the object subsequently should be visible when you access the object via the array.

When searching this topic, I’ve run across many questions asking how to store copies of objects in an array, so that this doesn’t happen, and the answer is always that you need to use clone. To me, this would SEEM to indicate that by default a reference would be stored.

So I was really confused when I encountered the following behavior…

$inner = ['key1'=>"value1"];

$outer = [];
$outer['inner'] = $inner;

$inner['key2'] = "value2";

print_r($inner);
echo "<br>";
print_r($outer['inner']);

OUTPUT:

Array ( [key1] => value1 [key2] => value2 )
Array ( [key1] => value1 )

I’ve been doing pretty serious PHP coding for 2 years now, and this seems to go against everything I thought I knew about arrays, so it’s really tripping me up.

Similar questions on Stack Exchange tend to get answers saying “you should refer to the documentation”. But nothing I can find in the docs address this clearly.

Advertisement

Answer

You’re just assigning the value of $inner at that time to $outer['inner']. After that, $outer['inner'] is its own array, it doesn’t maintain a reference to $inner. This is expected behaviour with arrays.

From the PHP documentation on arrays:

Array assignment always involves value copying. Use the reference operator to copy an array by reference.

So if you want to maintain a reference, you need to use the reference operator:

// Set the original values
$inner = ['key1' => 'value1'];

// Assign by reference
$outer = [];
$outer['inner'] = &$inner;

// Modify the original array afterwards
$inner['key2'] = 'value2';

You will then find that $outer['inner'] maintains the reference to $inner, even though it was changed after the assignment.

print_r($inner);
print_r($outer['inner']);

They will be the same:

Array ( [key1] => value1 [key2] => value2 )
Array ( [key1] => value1 [key2] => value2 )

Note: Using references is generally not a good idea and I can’t remember ever really needing them. There is a good discussion on Stack Overflow about this already.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement