emersonthis emersonthis - 1 year ago 39
PHP Question

Why are my PHP objects passed by reference

I'm seeing some confusing behavior related to reference/assignment in PHP...

private function doSomething($things)
foreach ($things as $thing) {
echo $thing->property; // 'foobar'
$copyThing = $thing;
echo $thing->property; // undefined

I expect this behavior when passing variables by reference (
) but I'm not trying to do that here and it seems to be happening anyway. What am I missing?

Answer Source

Just explaining my comment:

objects in foreach loops are always passed by reference

When you use a foreach loop for an array of objects the variable that you are using inside the loop is a pointer to that object so it works as a reference, any change on the object inside the loop is a change on the object outside. This is because:

objects are always passed by reference (@user3137702 quote)

Detailed and official explanation here.

When you copy and unset your variable:

$copyThing = $thing;

you are creating another pointer and unseting it, so the original value is a gone. As a matter of fact, since the foreach loop also uses a pointer the $things array is also affected.

check this ideone (notice the vardump [where the 'a' property is gone], as the output is the same as you got)

I do not know in which version it changed, if ever, as it seems like default object/pointer behavior

As a workaround (some ideas):

  1. Copy your initial array
  2. Use clone: $x = clone($obj); (As long as the default copy constructor works for your objects)