[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