php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74142 FilterIterator::accept called even though LimitIterator stops loop
Submitted: 2017-02-21 17:39 UTC Modified: 2017-02-21 18:45 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: nicolas dot levee at gmail dot com Assigned:
Status: Not a bug Package: SPL related
PHP Version: 7.0.16 OS: Linux
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.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: nicolas dot levee at gmail dot com
New email:
PHP Version: OS:

 

 [2017-02-21 17:39 UTC] nicolas dot levee at gmail dot com
Description:
------------
When a LimitIterator is use after a FilterIterator (or CallbackFilterIterator) the  accept function is call after the limit but if we invert the 2 iterator it's ok.

Test script:
---------------
class TestFilterIterator extends FilterIterator
{
    public function accept()
    {
        echo  __FUNCTION__, PHP_EOL;
        return true;
    }
}

$iterator = new ArrayIterator(array('a', 'b', 'c', 'd'));
$iterator = new TestFilterIterator($iterator);
$iterator = new LimitIterator($iterator, 0, 2);
foreach ($iterator as $k => $v) {
    echo PHP_EOL;
}

Expected result:
----------------
accept

accept



Actual result:
--------------
accept

accept

accept


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-02-21 18:45 UTC] requinix@php.net
-Summary: LimitIterator > FilterIterator issue +Summary: FilterIterator::accept called even though LimitIterator stops loop -Status: Open +Status: Not a bug
 [2017-02-21 18:45 UTC] requinix@php.net
This is expected behavior due to how iterators work. Take a look at
  http://php.net/manual/en/class.iterator.php
for more information about how the various methods are called by PHP.

To show the complex interaction between the three iterators it helps to add a couple items that the filter will reject...

What methods are being called in what order: https://3v4l.org/U61Ii
Annotated: https://gist.github.com/requinix/586a974f24a3ff8f3296f193bb871956

The key is that next() is invoked during iteration before valid(), and it's during the next() call that FilterIterator uses accept() - because it needs to advance to the next acceptable value. After this call is valid() and that's when LimitIterator's limit kicks in and can stop the loop; FilterIterator does not know that LimitIterator will not use the value it had advanced to.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 13:01:28 2024 UTC