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:7
Avg. Score:3.7 ± 0.9
Reproduced:6 of 7 (85.7%)
Same Version:2 (33.3%)
Same OS:4 (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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: arjen at react dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 18:01:29 2024 UTC