Edit report at https://bugs.php.net/bug.php?id=29992&edit=1
ID: 29992
Comment by: chealer at gmail dot com
Reported by: fletch at pobox dot com
Summary: foreach by reference corrupts the array
Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: linux
PHP Version: 5.0.1
Block user comment: N
Private report: N
New Comment:
The problematic behavior behing this issue is being tracked in #62132.
Previous Comments:
------------------------------------------------------------------------
[2014-12-06 23:33:13] dave dot mittner at gmail dot com
Though this may not be a "bug" it's certainly dangerous and unexpected enough to
deserve the level of importance.
As has been said, people expect the behavior of block-level scoping. I don't come from Java or
C++. I've programmed PHP for over a decade. I don't expect this kind of scope treatment
because of other languages. I expect it because it's a clean and logical practice that's
far safer than the contrary. Best practice for *any* language is to assume limited scope in blocks.
I've known that since I was a teenager.
In short, this should be changed. Even if it's a hack like unsetting it, that's safer than
the current processing model. And I don't buy that "we can't change it because people
use it" crap. I've had to rewrite entire systems due to changes in how PHP works. Stuff
breaking is a risk any time you update PHP and why you should pay attention to change lists.
------------------------------------------------------------------------
[2014-06-20 22:09:56] steve at fancyguy dot com
I have done this intentionally in some very lazy prototypes.
foreach($data as $k => &v) {
if (meets_complex_precondition($k)) {
break;
}
}
// do some stuff with $v potentially modifying it later
unset($v);
Comes in handy on occasion when working recursively by reference in deep arrays. Neat trick like
'array_map(null, $arr1, $arr2)'.
------------------------------------------------------------------------
[2014-02-11 03:34:59] xjis at msn dot com
well, i guess to be more exact, i should've said php doesn't have block scope support
whereas java/c++ does.
now i see that even javascript has added block scoping starting 1.7 (need to use 'let'
instead of 'var' to declare block-scoped variables)
------------------------------------------------------------------------
[2014-02-11 00:27:18] xjis at msn dot com
guys... i read through this entire thread and now i totally get it.
this is just a weird "side-effect" of having a language being "function-level
scope" instead of "block-level scope" and with referencing support.
and as long as the language stays being 'function-level scope' that also has the
referencing support, this is the expected behavior; and there's no easy way around it.
what ppl are expecting is exactly that of a block-level scope languages: having &v not
referencing anything after for-loop block ended. that's why ppl are keep referring to
C/C++/Java because these are all block-level scope languages; and why everyone wants for-loop to
"auto-unset" the &v after for-loop block ended; that would basically emulate/mimic the
behavior of block-level scope languages; but that is simply not the expected behavior for
function-level scope languages so you can't just make a special case only for for-loop blocks
--why would you make a special exception just for for-loop; why not for the entire language? then
now, you are asking PHP language to completely change itself from being a function-level scope
language into a block-level scope language
btw, javascript is also a function-level scope language, but it doesn't have this particular
problem because it doesn't support referencing
------------------------------------------------------------------------
[2013-12-04 21:50:33] gray dot bowman at gmail dot com
Just wanted to chime in that 9 years on, this is still totally unexpected behavior. Today, two
professional developers with years experience spent a couple hours trying to figure out why an array
that was demonstrably intact had its last element corrupted for apparently no reason once entering a
foreach.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=29992
--
Edit this bug report at https://bugs.php.net/bug.php?id=29992&edit=1