note 55152 deleted from control-structures.foreach by googleguy
| From: | googleguy@php.net | Date: | Wed, 14 Nov 2012 22:33:50 +0000 |
| Subject: | note 55152 deleted from control-structures.foreach by googleguy | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-191981@lists.php.net to get a copy of this message | ||
Note Submitter: mikeb at tracersinfo dot com
----
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".