From:             tomas_matousek at hotmail dot com
Operating system: WinXP
PHP version:      5.0.4
PHP Bug Type:     Scripting Engine problem
Bug description:  changing array during foreach iteration

Description:
------------
The behavior of foreach statment with reference value is not imho right if
the array gets modified during iteration.

See the code I've pasted here. If the array is written to (either by unset
or by a write operation) during iteration, the effect of & is canceled,
i.e. the values are not modified since the write operation.

This seems to me as bug because it is inconsistent with the "definition"
of foreach which should say that

foreach($a as $k => $v) {}

is (more or less) equivalent to 

$copy_of_a = $a;
while(next($copy_of_a))
{
  $k = key($copy_of_a);
  $v = $copy_of_a[$k];
}

With the &, one can deduce the following "definition":

foreach($a as $k =>& $v)  { }

is equivalent to 

$copy_of_a = $a;
while(next($copy_of_a))
{
  $k = key($copy_of_a);
  $v =& $a[$k];
}

Using =& operator, a new value should be added if it has been unset in the
original array.

Reproduce code:
---------------
$a = array(0,1,2,3,4,5,6,7,8);
$i = 0;
foreach ($a as $k =>& $v)
{
  $v+=100;

  if ($i++==2)
  {
    unset($a[5]);
  }
}
var_dump($a);

Expected result:
----------------
array(8) {
  [0]=>
  int(100)
  [1]=>
  int(101)
  [2]=>
  int(102)
  [3]=>
  int(3)      // modification of values stops here
  [4]=>
  int(4)
  [6]=>
  int(6)
  [7]=>
  int(7)
  [8]=>
  int(8)
}



Actual result:
--------------
array(8) {
  [0]=>
  int(100)
  [1]=>
  int(101)
  [2]=>
  int(102)
  [3]=>
  int(103)
  [4]=>
  int(104)
  [6]=>
  int(106)
  [7]=>
  int(107)
  [8]=>
  int(108)
  [5]=>        // note: the new value should be added here
  int(100)
}



-- 
Edit bug report at http://bugs.php.net/?id=33172&edit=1
-- 
Try a CVS snapshot (php4):   http://bugs.php.net/fix.php?id=33172&r=trysnapshot4
Try a CVS snapshot (php5.0): 
http://bugs.php.net/fix.php?id=33172&r=trysnapshot50
Try a CVS snapshot (php5.1): 
http://bugs.php.net/fix.php?id=33172&r=trysnapshot51
Fixed in CVS:                http://bugs.php.net/fix.php?id=33172&r=fixedcvs
Fixed in release:            http://bugs.php.net/fix.php?id=33172&r=alreadyfixed
Need backtrace:              http://bugs.php.net/fix.php?id=33172&r=needtrace
Need Reproduce Script:       http://bugs.php.net/fix.php?id=33172&r=needscript
Try newer version:           http://bugs.php.net/fix.php?id=33172&r=oldversion
Not developer issue:         http://bugs.php.net/fix.php?id=33172&r=support
Expected behavior:           http://bugs.php.net/fix.php?id=33172&r=notwrong
Not enough info:             
http://bugs.php.net/fix.php?id=33172&r=notenoughinfo
Submitted twice:             
http://bugs.php.net/fix.php?id=33172&r=submittedtwice
register_globals:            http://bugs.php.net/fix.php?id=33172&r=globals
PHP 3 support discontinued:  http://bugs.php.net/fix.php?id=33172&r=php3
Daylight Savings:            http://bugs.php.net/fix.php?id=33172&r=dst
IIS Stability:               http://bugs.php.net/fix.php?id=33172&r=isapi
Install GNU Sed:             http://bugs.php.net/fix.php?id=33172&r=gnused
Floating point limitations:  http://bugs.php.net/fix.php?id=33172&r=float
No Zend Extensions:          http://bugs.php.net/fix.php?id=33172&r=nozend
MySQL Configuration Error:   http://bugs.php.net/fix.php?id=33172&r=mysqlcfg

Reply via email to