tags:

views:

130

answers:

1

Hi I am trying to get RecursiveDirectoryIterator class using a extension on the FilterIterator to work but for some reason it is iterating on the root directory only.

my code is this.

    class fileTypeFilter extends FilterIterator
{
    public function __construct($path)
    {
        parent::__construct(new RecursiveDirectoryIterator($path));
    }  
    public function accept()
    {
        $file = $this->getInnerIterator()->current();
        return preg_match('/\.php/i', $file->getFilename());
    }    

}

$it = new RecursiveDirectoryIterator('./');
$it = new fileTypeFilter($it);

foreach ($it as $file)
{
    echo $file;
}

my directory structure is something like this.

-Dir1
--file1.php
--file2.php
-Dir2
--file1.php

etc etc

But as I said before the class is not recursively iterating over the entire directory structure and is only looking at the root.

Question is, how do use a basic RescursiveDirectoryIterator to display folders and then run the FilterIterator to only show the php files in those directorys?

Cheers

+2  A: 

The FilterIterator should accept another iterator through its constructor. In order for the automatic recursion to happen, you need to use a RecursiveIteratorIterator to iterate over the RecursiveIterator. You don't need to, but if you don't, then the burden of calling hasChildren() and getChildren() etc... is on you.

Here's a sample. I didn't bother to accept any arguments in the constructor for FileTypeFilterIterator, although that would be a nice addition if you wanted to be able to alter the regex. But, otherwise, you don't need to define a constructor.

$it = new FileTypeFilterIterator (
    new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path),
        RecursiveIteratorIterator::SELF_FIRST
    )
);


class FileTypeFilterIterator extends FilterIterator
{
    public function __construct(Iterator $iter)
    {
        parent::__construct($iter);
    }
    public function accept()
    {
        $file = $this->getInnerIterator()->current();
        return preg_match('/\.php/i', $file->getFilename());
    }

}
foreach($it as $name => $object){
    echo "$name\n";
}

Btw, in this case, you might as well just use RegexIterator instead of extending FilterIterator.

chris
Thanks Chris, would love to pick your brain on this stuff! :)
Jared