|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76387 Different behavior between Array and ArrayIterator in foreach loop...
Submitted: 2018-05-29 07:55 UTC Modified: 2018-06-26 08:48 UTC
From: Evgeny dot Mazanik at gmail dot com Assigned:
Status: Duplicate Package: SPL related
PHP Version: 7.2.6 OS: Windows 10
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: Evgeny dot Mazanik at gmail dot com
New email:
PHP Version: OS:


 [2018-05-29 07:55 UTC] Evgeny dot Mazanik at gmail dot com
From manual page:

Different behavior when using Array and ArrayIterator in a foreach loop when using unset () for an associative array.

1. When using an Array in a loop and removing an element in the body of the loop, the loop is executed across all elements of the array.

2. When using ArrayIterator in a loop and deleting an element in the body of the loop, the loop is NOT performed on all elements of the array.

A similar problem:

Test script:

Actual also for PHP 7.2.4, 7.2.6

Expected result:

Via array:
Via ArrayIterator:

Actual result:
Via array:
Via ArrayIterator:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2018-06-01 10:51 UTC] a at b dot c dot de
For what it's worth, of course, I'll point out that this is the same difference in behaviour as when arrays vs. ArrayObjects are passed as arguments to functions. The array and the ArrayObject are both passed by value; in the array's case is the sequence of key/value pairs it is made up of; the ArrayObject's value is the ArrayObject itself.

In the same wise, the foreach() iterates over the value it is given to iterate over. That value isn't replaced while the loop is iterating. Changing the contents of an array changes its value (but the foreach doesn't see that - it's iterating over the value it was given). But changing the contents of an ArrayObject doesn't change its value - it's still the same ArrayObject, and its value is still the one given to the foreach).

$foo = ['a','b']; // The value of $foo is the sequence 0=>'a', 1=>'b'
// $foo = new ArrayIterator(['a']); // The value of $foo is an ArrayIterator object.

foreach($foo as $b)
	echo $b;
	$foo[] = 'f';	// Append to $foo

echo "\n",count($foo),"\t",join($foo);

Bug #75173 addressed an instance of the opposite problem to the current happening: the value of the Iterator object is the Iterator object, so the loop should have been iterating over that Iterator's elements.
 [2018-06-26 08:48 UTC]
-Status: Open +Status: Duplicate -Type: Documentation Problem +Type: Bug
 [2018-06-26 08:48 UTC]
Duplicate of bug #70246
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Thu Mar 23 04:03:40 2023 UTC