php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52560 FilterIterator errantly returns null for first element
Submitted: 2010-08-07 04:40 UTC Modified: 2013-09-12 22:40 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:1 of 2 (50.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: tobias382 at gmail dot com Assigned: levim
Status: Not a bug Package: SPL related
PHP Version: 5.3SVN-2010-08-07 (snap) OS: Ubuntu 10.04
Private report: No CVE-ID:
 [2010-08-07 04:40 UTC] tobias382 at gmail dot com
Description:
------------
Even when a FilterIterator subclass accepts all elements, it returns NULL for the 
first element in the original array. There are a few methods to correct this 
behavior, noted in the attached test script.

Test script:
---------------
<?php
class FooIterator extends FilterIterator {
    /*
    // Forces this class to produce expected behavior below
    // (i.e. 1, 2, NULL instead of NULL, 2, NULL)
    public function __construct(Iterator $iterator) {
        parent::__construct($iterator);
        $iterator->rewind();
    }
    */
    // Should cause all elements to be accepted
    public function accept() {
        return true;
    }   
    /* 
    // Another way to force this class to produce expected behavior below
    public function current() {
        return $this->getInnerIterator()->current();
    }
    */
}

$array = array(1, 2); 

/*
// What should happen in subsequent blocks
$iterator1 = new ArrayIterator($array);
var_dump($iterator1->current()); // int(1)
$iterator1->next();
var_dump($iterator1->current()); // int(2)
$iterator1->next();
var_dump($iterator1->current()); // NULL
*/

// The problem
$iterator2 = new FooIterator(new ArrayIterator($array));
var_dump($iterator2->current()); // NULL <-- this should be int(1)
$iterator2->next();
var_dump($iterator2->current()); // int(2)
$iterator2->next();
var_dump($iterator2->current()); // NULL

// Exhibits correct behavior with no changes to FooIterator
$iterator3 = new FooIterator(new ArrayIterator($array));
$iterator3->rewind(); // This line shouldn't be needed, but is to force expected behavior
var_dump($iterator3->current()); // int(1)
$iterator3->next();
var_dump($iterator3->current()); // int(2)
$iterator3->next();
var_dump($iterator3->current()); // NULL

Expected result:
----------------
int(1)
int(2)
NULL
int(1)
int(2)
NULL

Actual result:
--------------
NULL
int(2)
NULL
int(1)
int(2)
NULL

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-08-07 04:49 UTC] tobias382 at gmail dot com
Small amendment: $iterator->rewind() should be $this->rewind() in the overridden 
constructor in the test script.
 [2010-08-07 05:03 UTC] colder@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: colder
 [2013-09-12 22:40 UTC] levim@php.net
-Status: Assigned +Status: Not a bug -Assigned To: colder +Assigned To: levim
 [2013-09-12 22:40 UTC] levim@php.net
This is simply a common misunderstanding. Iterators need to be rewound before use. 
Whether that was a good design or not is debatable, but nonetheless this is not a 
bug.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 15:01:54 2014 UTC