Tuesday, July 10, 2007

[PHP] Foreach expord Arrary

Using PHP5's foreach "as reference" can bite you!

Three guys in my office spent about a day chasing this one's tail, that was causing aberrant behavior in the values of elements of an array. It turns out to be a consequence of the nature of references, generally.

If you create a reference to a variable, all names for that variable (including the original) BECOME REFERENCES. To paraphrase "The Highlander," if you want a name to OWN a piece of data, "there can be only one."

To illustrate this point, consider the following code:

<?php

$f = array(
0 => array('value' => 'three'),
1 => array('value' => 'three')
);

foreach ( $f as $k => &$v ) {
$v['value'] = 'one';
}

$a = $f;
$b = $f;

$b[0]['value'] = 'two';
$b[1]['value'] = 'two';

var_dump($a, $b);

?>

Upon execution, you will find that, although you would expect $a to contain two arrays with 'value' of 'one', $a and $b are identical -- i.e., the changes of []['value'] to 'two' have happened in both arrays. But, upon further examination of the var_dumps, you will see that both sets' elements [0] and [1] are preceded with "&": they are references!

The easy solution to this problem turns out to be: unset the foreach "as-reference" variable ($v) at the bottom of your foreach loop. This allows the original variable (or array member) to resume ownership of the value and dissolves its "reference-ness".

No comments:

Google AdSense