NYCPHP Meetup

NYPHP.org

[nycphp-talk] Pass-by-value and lazy copy

Rob Marscher rmarscher at beaffinitive.com
Mon Nov 26 13:33:13 EST 2007


On Nov 22, 2007, at 4:56 PM, Paul Houle wrote:
> By using the '&' operator in function calls and in assigments,  you  
> can get PHP 4 to behave a lot like PHP 5,  but weird things will  
> happen if you miss using '&' even once.


And then when you have to port everything to PHP5, you get other weird  
things happening because of the workarounds you did for PHP4.  :-)  I  
would recommend if you're still using PHP4 (hopefully you're not for  
much longer ;), you should try to avoid using references to prevent  
unnecessary variable copying because it makes the PHP5 migration more  
difficult.

I'm not sure I should exactly blame the following on the PHP4->5  
changes... the code is somewhat questionable to begin with... but it  
followed from us attempting to use references in PHP4 to prevent  
unnecessary copying.  Check this out:

We had code that essentially boiled down to the following in PHP4:

class SomeClass {
}
$someLoop = array(0 => 'a', 1 => 'b', 2 => 'c');
$arr = array();
foreach ($someLoop as $key => $value) {
   $someObj = & new SomeClass();
   $someObj->val = $value;
   $arr[$key] = & $someObj;
}
print_r($arr);

Here's the output:
Array (
     [0] => SomeClass Object ( [val] => a )
     [1] => SomeClass Object ( [val] => b )
     [2] => SomeClass Object ( [val] => c )
)

Now "& new" is deprecated in PHP5 because objects are always passed by  
reference anyway.  So we wrote a script the replaced "& new" with just  
"new."  However... now our loop looks like this:

foreach ($someLoop as $key => $value) {
   $someObj = new SomeClass();
   $someObj->val = $value;
   $arr[$key] = & $someObj;
}

And here's what happens (this is actually the same in PHP4 and PHP5):
Array (
     [0] => SomeClass Object ( [val] => c )
     [1] => SomeClass Object ( [val] => c )
     [2] => SomeClass Object ( [val] => c )
)

Whoops...  so we had to go through and find these cases and fix it to  
not use references for assignment since it doesn't need them either in  
PHP5:
foreach ($someLoop as $key => $value) {
   $someObj = new SomeClass($value);
   $someObj->val = $value;
   $arr[$key] = $someObj;
}

Hehe... or write it like this in the first place:
foreach ($someLoop as $key => $value) {
   $arr[$key] = new SomeClass($value);
   $arr[$key]->val = $value;
}

The actual code was more complicated and the original way it was  
written made more sense than it seems from the super simplified example.

-Rob




More information about the talk mailing list