emersonthis
emersonthis

Reputation: 33368

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;
        unset($copyThing->property);
        echo $thing->property; // undefined

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

Upvotes: 0

Views: 337

Answers (1)

M.M
M.M

Reputation: 2304

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;
unset($copyThing->property);

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)

Upvotes: 3

Related Questions