note 92116 added to control-structures.foreach
| From: | Krzysztof-ksobolewskiato2dotpl at osu1 dot php dot net | Date: | Thu, 09 Jul 2009 11:50:02 +0000 |
| Subject: | note 92116 added to control-structures.foreach | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-158101@lists.php.net to get a copy of this message | ||
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;
}
?>
----
Server IP: 194.24.174.37
Probable Submitter: 89.79.61.55
----
Manual Page -- http://www.php.net/manual/en/control-structures.foreach.php
Edit -- https://master.php.net/note/edit/92116
Del: integrated -- https://master.php.net/note/delete/92116/integrated
Del: useless -- https://master.php.net/note/delete/92116/useless
Del: bad code -- https://master.php.net/note/delete/92116/bad+code
Del: spam -- https://master.php.net/note/delete/92116/spam
Del: non-english -- https://master.php.net/note/delete/92116/non-english
Del: in docs -- https://master.php.net/note/delete/92116/in+docs
Del: other reasons-- https://master.php.net/note/delete/92116
Reject -- https://master.php.net/note/reject/92116
Search -- https://master.php.net/manage/user-notes.php