tags:

views:

54

answers:

2

I just read this answer by Bill Karwin.

Note that the $node is pass by reference.

I always thought that variable created there is only ever temporary and exists only until the end of the loop (or maybe it remains set to the last iteration - I have not tested it).

So, what are the advantages of making it pass by reference?

I'm sure there is one, but I can't figure it out yet.

+2  A: 

The advantage is that it lets you manipulate the array directly.

foreach ($array as $key => $node) {
    $array[$key]['foo'] = 'bar';
}

can be made shorter and more efficient like this:

foreach ($array as &$node) {
    $node['foo'] = 'bar';
}

In this case $node is not a copy of the contents of the array entry, but a reference to the actual array entry; whatever you do to it, you do to the array.

deceze
+1 Thanks, I just realised I use the former a bit and can now be more efficient.
alex
+5  A: 

It has nothing to do with being faster or more efficient.

PHP implements copy-on-write so a variable may refer to the same area of memory until you change its value. Then when you change the variable, PHP decides whether or not to create a copy depending on whether you're accessing it by value or by reference.

Access by value -- changes to a variable creates a copy:

$a = array("abc");

foreach ($a as $element) {
  $element = "def";
}

print_r($a);

Array
(
    [0] => abc
)

Access by reference -- changes to a variable affect the original copy:

foreach ($a as &$element) {
  $element = "def";
}

print_r($a);

Array
(
    [0] => def
)

Note that all objects in PHP 5 are accessed by reference without using the & operator.
This is a good reason to use objects!

Be very careful using references in PHP, because they can have confusing effects.

Be sure to read this blog: Do not use PHP references by PHP core developer Johannes Schlüter

Bill Karwin
+1 Thanks for providing an answer; I was hoping you would!
alex
*Be careful!* `$foo = array(1, 2, 3); foreach($foo as } $bar = 99; echo $foo[2];` -- this prints "99". "$bar" is still a reference after the loop ends. You can and will shoot yourself in the foot if you aren't careful.
Charles
@Charles Thanks for the tip.
alex