php foreach by reference

Here’s an interesting “feature” (bug?) for php. Recent PHP versions support this syntax for foreach:

foreach ($myarray as &$v)
  $v['koko']='lala';

This allows easy changes to the actual table by using references and not acting on a copy.

– but –

If you do this:

$myarray=array(array('a'=>1), array('a'=>2), array('a'=>3));

foreach ($myarray as &$v)
  $v['b']=1;

foreach ($myarray as $v);

print_r($myarray);

You manage to remove the last element of $myarray (!!!). This is the output:

Array
(
    [0] => Array
        (
            [a] => 1
            [b] => 1
        )

    [1] => Array
        (
            [a] => 2
            [b] => 1
        )

    [2] => Array
        (
            [a] => 2
            [b] => 1
        )

)

Now, if you change the code to:

$myarray=array(array('a'=>1), array('a'=>2), array('a'=>3));

foreach ($myarray as &$v)
  $v['b']=1;

foreach ($myarray as $v2);

print_r($myarray);

The bug is gone. The output is correct:

Array
(
    [0] => Array
        (
            [a] => 1
            [b] => 1
        )

    [1] => Array
        (
            [a] => 2
            [b] => 1
        )

    [2] => Array
        (
            [a] => 3
            [b] => 1
        )
)

To my knowledge, this happens because $v is kept as a reference to the last element when the first foreach is finished. Then, when the second foreach is ran, some assignments are performed to $v, destroying its last element.