|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68153 Iteration error, if use object with ArrayAccess
Submitted: 2014-10-04 14:47 UTC Modified: 2014-10-06 02:08 UTC
From: zhuk2205 at gmail dot com Assigned:
Status: Open Package: SPL related
PHP Version: 5.5.17 OS: Mac OS
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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Bug Type:
From: zhuk2205 at gmail dot com
New email:
PHP Version: OS:


 [2014-10-04 14:47 UTC] zhuk2205 at gmail dot com
If create object and implement it ArrayAccess and Iterator interfaces, we have a problem with remove elements from storage with use ArrayAccess.

Likely PHP \Iterator system not find "active" key after remove active element, and use key as active next key. As result, in next iteration will be invalid key.

Test script:

class MyModel

class Collection implements \ArrayAccess, \Iterator
    private $storage = array();

    public function offsetExists($offset)
        return isset($this->storage[$offset]);

    public function offsetGet($offset)
        return $this->storage[$offset];

    public function offsetSet($offset, $value)
        if (null === $offset) {
            $this->storage[] = $value;
        } else {
            $this->storage[$offset] = $value;

    public function offsetUnset($offset)
        unset ($this->storage[$offset]);

    public function current()
        return current($this->storage);

    public function next()
        return next($this->storage);

    public function key()
        return key($this->storage);

    public function valid()
        return key($this->storage) !== null;

    public function rewind()

    public function count()
        return count($this->storage);

class MyCollectionModel
    private $collection;

    public function __construct()
        $this->collection = new Collection();

    public function addElement($element)
        $this->collection[] = $element;

    public function removeMyModels()
        foreach ($this->collection as $index => $value) {
            if ($value instanceof MyModel) {
                unset ($this->collection[$index]);

// Create collection
$myCollection = new MyCollectionModel();

// Add own models to collections
for ($i = 0; $i < 10; $i++) {
    $myCollection->addElement(new MyModel());

// Remove owl models from collection

// So, not all elements removed

Expected result:
Remove all "MyModel" instances from collection.

Actual result:
Not all removed objects.


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-06 02:08 UTC]
You can get the same behaviour with this code:

  $a = [1,2,3];

  for (reset($a); ($key = key($a)) !== null; next($a)) {
  var_dump($a); // [1] => 2

It's not recommended practice to remove elements from a collection while you iterate over it; therefore I don't think we can consider this to be a bug.
 [2017-11-02 00:33 UTC] eric dot poe at gmail dot com
Is this a bug? If not, can it be closed?
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon May 20 12:01:33 2024 UTC