note 92116 deleted from control-structures.foreach by googleguy
| From: | googleguy@php.net | Date: | Wed, 14 Nov 2012 22:28:03 +0000 |
| Subject: | note 92116 deleted from control-structures.foreach by googleguy | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-191962@lists.php.net to get a copy of this message | ||
Note Submitter: Krzysztof - ksobolewski at o2 dot pl
----
The weird behaviour of references in foreach remains as long as in PHP 5.2.08 (Linux) and PHP 5.2.9
(Windows XP). The simplest example would be:
<?php
$a = array('a', 'b','c');
foreach($a as &$row){
//you don't have to do anything here
}
print_r($a);
foreach($a as $row){
echo "<br />".$row;
}
?>
the result of print_r will be correct - array of ('a','b','c') values.
The second foreach, however, would
produce a,b,b. For all arrays, regardless of size, it would be the n-1 element
(the element right before the last one). Eg. for
'a','b','c','d','e','f', the script
would produce a,b,c,d,e,e.
There are few solutions to this:
1. safest - avoid using references in foreach; so instead of
<?php
foreach($a as &$row){
// do something, eg.
$row = trim($row);
}
?>
you would use
<?php
foreach($a as $i=>$row){
// do something on row, eg.
$row = trim($row);
// replace the row in the table
$a[$i]=$row;
}
?>
decrease of performance is the cost, however
2. equally safe and more usable - unset the element reference right after the foreach loop with
references, eg.:
<?php
$a = array('a', 'b','c');
foreach($a as &$row){
//you don't have to do anything here
}
unset ($row)); // it is safe now to use $row again
print_r($a);
foreach($a as $row){
echo "<br />".$row;
}
?>
3. use references in both case; it seems that iterations work correct if you use &$row in both
loops or don't use it in any:
<?php
$a = array('a', 'b','c');
foreach($a as &$row){
//you don't have to do anything here
}
print_r($a);
// works OK now even without unset($row)
foreach($a as &$row){
echo "<br />".$row;
}
?>
4. use references in foreach only inside functions or methods; outside the function scope it should
be safe
<?php
function cleanTable($a){
foreach($a as &$row){
$row = trim($row);
}
}
$a = array('a','b','c');
cleanTable($a);
foreach($a as $row){
echo "<br />".$row;
}
?>
drawbacks: NONE! I Quite contrary, the code looks more tidy.
5. avoid using the same variable names for referenced and non-referenced values; for example, in the
first case use &$rRow, and in the second one - $row. It's neither elegant, nor efficient,
though, as each new variable lowers the application performance a bit.
<?php
$a = array('a', 'b','c');
foreach($a as &$rRow){ // $rRow for 'referenced row'
//you don't have to do anything here
}
print_r($a);
foreach($a as $row){
echo "<br />".$row;
}
?>