Bug #29992 [Com]: foreach by reference corrupts the array

From: Date: Fri, 20 May 2016 14:34:57 +0000
Subject: Bug #29992 [Com]: foreach by reference corrupts the array
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201209@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=29992&edit=1

 ID:                 29992
 Comment by:         ourtusenka at yandex dot ru
 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:

I have the same problem with php 5.6 on OpenServer.
Before I never meet it; I don't use reference. But foreach do the same with my array.
So:
foreach ( $items as $item ) {
    //..echo single $item
}
Last element of $items is disappeared;


Previous Comments:
------------------------------------------------------------------------
[2015-01-01 20:18:52] chealer at gmail dot com

The problematic behavior behing this issue is being tracked in #62132.

------------------------------------------------------------------------
[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

------------------------------------------------------------------------


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


Thread (43 messages)

« previous php.bugs (#201209) next »