Lies! Darn Lies!

    Harry Fuecks
    Share

    Been talking to Marcus Boerger, via email, about the PHP 5 Standard Library article and need to confess ;)

    Marcus makes a very good point about the DirectoryReader example I used;

    Your DirectoryReader is wrong. It does the non file skipping in valid, but it should be done in next().

    But after the necessary changes it still has a major design flaw. It uses recursion. And Iterators are about unfolding.

    So what you should do is preventing that recursion and if you look at the result and how much it took you to complete it correctly you see why using FilterIterator would have been better. That one can be used to filter out the non files easily and it makes clear why iterators can be used for functional programming – in this scenario the filter algorithm provided by FilterIterator doesn’t know anything about your data.

    Here’s the problem class plus code using it;


    class DirectoryReader extends DirectoryIterator {

    function __construct($path) {
    parent::__construct($path);
    }

    function current() {
    return parent::getFileName();
    }

    function valid() {
    if ( parent::valid() ) {
    if ( !parent::isFile() ) {
    parent::next();
    return $this->valid();
    }
    return TRUE;
    }
    return FALSE;
    }

    function rewind() {
    parent::rewind();
    }
    }

    // Create a directory reader for the current directory
    $Reader = new DirectoryReader('./');

    // Loop through the files in the directory ?!?
    foreach ( $Reader as $Item ) {
    echo $Item.'
    ';
    }

    Anyone want to take up the guantlet and re-implement?

    As I understand what Marcus is saying, the alternative is to use DirectoryIterator itself then pass it to something extending FilterIterator (or perhaps better extending DirectoryFilterDots) – the “spec” is for something to list only the files in a given directory, ignoring the parent and current nodes.