php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70246 ArrayIterator skips next element when current element is unset in foreach.
Submitted: 2015-08-12 12:34 UTC Modified: 2018-06-26 16:57 UTC
Votes:3
Avg. Score:3.3 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:2 (66.7%)
From: arjen at react dot com Assigned:
Status: Verified Package: SPL related
PHP Version: 7.0.0beta3 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2015-08-12 12:34 UTC] arjen at react dot com
Description:
------------
ArrayIterator skips next element when current element is unset in foreach.

http://3v4l.org/uUoaH

Test script:
---------------
<?php

$ar = [1,2,3,4,5];
$i = new ArrayIterator($ar);

foreach ($i as $k => $e) {
    var_dump($e);
    if ($k === 1) {
        unset($i[$k]);
    }
}

echo '---------' . PHP_EOL;

foreach ($i as $e) {
    var_dump($e);
}

Expected result:
----------------
int(1)
int(2)
int(4)
int(5)
---------
int(1)
int(3)
int(4)
int(5)

Actual result:
--------------
int(1)
int(2)
int(3)
int(4)
int(5)
---------
int(1)
int(3)
int(4)
int(5)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-08-18 11:56 UTC] arjen at react dot com
Expected and actual result are swapped, my mistake..

Expected result:
--------------
int(1)
int(2)
int(3)
int(4)
int(5)
---------
int(1)
int(3)
int(4)
int(5)

Actual result:
----------------
int(1)
int(2)
int(4)
int(5)
---------
int(1)
int(3)
int(4)
int(5)
 [2015-09-19 18:55 UTC] j dot tvr at centrum dot cz
This is probably not a bug. When you unset current element, the internal array pointer moves to the next element. Therefore what you're doing is essentially equivalent to https://3v4l.org/rWQq8:

<?php
$ar = [1, 2, 3, 4, 5];
$it = new ArrayIterator($ar);

foreach ($it as $k => $v) {
    if ($k === 0) $it->next(); // eq. to unset($it[0]);
    echo "\$ar[$k] = $v;\n";
}

echo "\n";
print_r(iterator_to_array($it));
 [2016-03-18 11:45 UTC] david at grudl dot com
Similar bug with stdClass and ArrayIterator: https://3v4l.org/2A1pf
 [2018-06-26 08:44 UTC] derick@php.net
This bug is still being encountered in the wild, and it cost us considerable time to figure out what was wrong: https://github.com/mongodb/mongo-php-library/pull/544/files#diff-d4c8c6dc8769324fc27cfdac19f05cafR88
 [2018-06-26 16:57 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2018-06-26 16:57 UTC] cmb@php.net
This regression has been introduced with commit 2b6a568[1].  The
first change in array_015.phpt already shows the problem.

[1] <http://git.php.net/?p=php-src.git;a=commit;h=2b6a568df119487f73abb43edd2ae82e83945356>
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Aug 24 18:01:27 2019 UTC