|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #55157 ArrayIterator::offsetUnset(); does not work correctly
Submitted: 2011-07-07 06:52 UTC Modified: 2021-04-13 11:54 UTC
Avg. Score:4.4 ± 0.8
Reproduced:18 of 18 (100.0%)
Same Version:7 (38.9%)
Same OS:8 (44.4%)
From: olav at fwt dot no Assigned: cmb (profile)
Status: Closed Package: SPL related
PHP Version: Irrelevant OS: openSUSE 11.4/Debian 5
Private report: No CVE-ID: None
 [2011-07-07 06:52 UTC] olav at fwt dot no
ArrayIterator always skips the second element in the array when calling 
offsetUnset(); on it while looping through.

Using the key from iterator and unsetting in the actual ArrayObject works as 

Running php 5.3.5 on openSUSE 11.4
Replicated same bug on Debian 5 running PHP 5.2.6-1+lenny9.

php5 is installed as binary on both systems, SPL is builtin package.

Test script:

// Create a array range from 0 to 9
$a = new ArrayObject( range( 0,9 ) );
$b = new ArrayIterator( $a );
for ( $b->rewind(); $b->valid(); $b->next() )
    echo "#{$b->current()} - \r\n";
    $b->offsetUnset( $b->key() );

Expected result:
Expected a list of from 0 to 9 echoed out.

Actual result:
Lists out 0 and then 2-9 leaving index 1 untouched in the original ArrayObject.


Add a Patch

Pull Requests

Pull requests:

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2011-07-07 07:05 UTC]
-Status: Open +Status: Assigned -Assigned To: +Assigned To: colder
 [2011-07-07 07:17 UTC]
Just to narrow the scope of the bug a bit:

$a = range( 0,9 );
$b = new ArrayIterator( $a );
foreach($b as $k=>$v) {

var_dump($b->getArrayCopy()); // why is 1 still around?
 [2011-07-07 07:18 UTC]
Sorry, I should clarify that the code above gives:

array(1) { [1]=> int(1) }

Whereas you'd probably expect:

array(0) { }
 [2011-07-19 15:09 UTC] gergo at gergoerdosi dot com
I have the same problem, used this code:

$items = new ArrayObject(array(1, 2, 3, 4, 5));

foreach($items as $item) {
	if(in_array($item, array(2, 3, 4))) {


Expected result: array(1, 5), actual result: array(1, 3, 5).
 [2011-07-19 15:18 UTC] gergo at gergoerdosi dot com
Please ignore my comment above. The offsetUnset() method unsets elements using 
their index. Changing the code to this gives the expected result (0, 4):

$items = new ArrayObject(array(0, 1, 2, 3, 4));

foreach($items->getArrayCopy() as $item) {
	if(in_array($item, array(1, 2, 3))) {

 [2012-11-19 01:17 UTC]
It seems that calling `ArrayIterator::offsetUnset` moves the internal pointer to 
the next element when removing the first index:

$a = range( 0,3 );
$b = new ArrayIterator( $a );

for ($b->rewind(); $b->valid(); ) {
    echo "{$b->key()} => {$b->current()}\n";

 [2014-08-29 06:46 UTC] jan dot kahoun at heureka dot cz
I have the same problem, are you planning to fix it?
 [2015-04-19 00:47 UTC] mw dot wanrooij at vodafonevast dot nl
Same problem here, as mentioned earlier: "It seems that calling `ArrayIterator::offsetUnset` moves the internal pointer to 
the next element when removing the first index"

Is there any progress on a fix?
 [2017-10-24 07:25 UTC]
-Status: Assigned +Status: Open -Assigned To: colder +Assigned To:
 [2020-04-22 07:24 UTC] alexinbeijing at gmail dot com
This bug is already fixed and the report should be closed.

The original repro code prints keys 0, 2, 4, 6, and 8, which is expected. This is because when ::offsetUnset() deletes the current iteration key, it bumps the current iteration position to the next element. Then, when ::next() is called, it bumps the position forward again. So it results in iterating over every second element.

The subsequent repro code which was stated to only leave key 1 in place actually leaves all the odd-numbered keys (1, 3, 5, 7, and 9) in place, for the same reason stated above.

Just seeing if documentation for ::offsetUnset() can be updated to make this clearer...
 [2020-06-09 09:32 UTC] alexinbeijing at gmail dot com
The following pull request has been associated:

Patch Name: Add note on behavior of ArrayIterator::offsetUnset when used on current iteration index
On GitHub:
 [2020-06-09 09:33 UTC] alexinbeijing at gmail dot com
Just submitted a PR to update the documentation on this issue...
 [2021-04-13 11:54 UTC]
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2021-04-13 11:54 UTC]
Indeed, fixed as of PHP 7.0.0.
 [2021-04-13 11:54 UTC]
Indeed, fixed as of PHP 7.0.0.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Jul 17 23:01:28 2024 UTC