0

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.

Agent Friday
  • 169
  • 2
  • 12
  • 3
    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. – BadHorsie Aug 27 '20 at 16:56
  • 1
    Does that answer your question? https://stackoverflow.com/questions/2030906/are-arrays-in-php-copied-as-value-or-as-reference-to-new-variables-and-when-pas – Ihor Vyspiansky Aug 27 '20 at 16:57
  • @IhorVyspiansky: No, that question is referring to assignment of the entire array, not adding elements to an array. – Agent Friday Aug 27 '20 at 17:17
  • @BadHorsie: Can you point me to anything that explains this in the php docs? Seems it should be made more obvious. – Agent Friday Aug 27 '20 at 17:22
  • Yep, see my full answer below for details. – BadHorsie Aug 27 '20 at 17:34

1 Answers1

0

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.

BadHorsie
  • 14,135
  • 30
  • 117
  • 191
  • The part you quote from the manual "Array assignment always involves value copying" is not referring to adding elements into an array, but rather assigning a whole array. – Agent Friday Aug 27 '20 at 17:35
  • 1
    @AgentFriday No it's the same principle. I don't know what else to tell you, that's just how it works in PHP. – BadHorsie Aug 27 '20 at 17:39
  • Where might I find in the manual that tells me it's the same principle? Sorry, I'm just at a loss for how I got this far without understanding this and want to get a better grasp on it. – Agent Friday Aug 27 '20 at 17:44
  • You probably need to look deeper at [how PHP manages variables internally](https://entwickler.de/webandphp/how-php-manages-variables-125644.html), the software principle of [copy on write](https://stackoverflow.com/questions/628938/what-is-copy-on-write), and possibly [how PHP arrays work internally](https://nikic.github.io/2012/03/28/Understanding-PHPs-internal-array-implementation.html). – BadHorsie Aug 27 '20 at 18:21