Bug #74142 [Opn->Nab]: FilterIterator::accept called even though LimitIterator stops loop
| From: | requinix@php.net | Date: | Tue, 21 Feb 2017 18:45:21 +0000 |
| Subject: | Bug #74142 [Opn->Nab]: FilterIterator::accept called even though LimitIterator stops loop | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-207497@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74142&edit=1
ID: 74142
Updated by: requinix@php.net
Reported by: nicolas dot levee at gmail dot com
-Summary: LimitIterator > FilterIterator issue
+Summary: FilterIterator::accept called even though
LimitIterator stops loop
-Status: Open
+Status: Not a bug
Type: Bug
Package: SPL related
Operating System: Linux
PHP Version: 7.0.16
Block user comment: N
Private report: N
New Comment:
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.
Previous Comments:
------------------------------------------------------------------------
[2017-02-21 17:39:44] 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
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74142&edit=1