The DirectoryIterator class

(PHP 5, PHP 7, PHP 8)

Introduction

The DirectoryIterator class provides a simple interface for viewing the contents of filesystem directories.

Class synopsis

class DirectoryIterator extends SplFileInfo implements SeekableIterator {
/* Methods */
public __construct(string $directory)
public current(): mixed
public getBasename(string $suffix = ""): string
public isDot(): bool
public key(): mixed
public next(): void
public rewind(): void
public seek(int $offset): void
public __toString(): string
public valid(): bool
/* Inherited methods */
public SplFileInfo::getBasename(string $suffix = ""): string
public SplFileInfo::openFile(string $mode = "r", bool $useIncludePath = false, ?resource $context = null): SplFileObject
public SplFileInfo::setFileClass(string $class = SplFileObject::class): void
public SplFileInfo::setInfoClass(string $class = SplFileInfo::class): void
}

Table of Contents

add a note add a note

User Contributed Notes 8 notes

up
50
krystianmularczyk at gmail dot com
15 years ago
Shows us all files and catalogues in directory except "." and "..".

<?php

foreach (new DirectoryIterator('../moodle') as $fileInfo) {
    if(
$fileInfo->isDot()) continue;
    echo
$fileInfo->getFilename() . "<br>\n";
}

?>
up
10
rogier at dsone dot nl
11 years ago
Beware of the behavior when using FilesystemIterator::UNIX_PATHS, it's not applied as you might expect.

I guess this flag is added especially for use on windows.
However, the path you construct the RecursiveDirectoryIterator or FilesystemIterator with will not be available as a unix path.
I can't say this is a bug, since most methods are just purely inherited from DirectoryIterator.

In my test, I'd expected a complete unix path. Unfortunately... not quite as expected:

<?php
        
// say $folder = C:\projects\lang

       
$flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS;
       
$d_iterator = new RecursiveDirectoryIterator($folder, $flags);

        echo
$d_iterator->getPath();

?>

expected result: /projects/lang (or C:/projects/lang)
actual result: C:\projects\lang
up
2
alvaro at demogracia dot com
6 years ago
DirectoryIterator is just an lightweight SplFileInfo iterator and its methods operate on whatever item the internal cursor points to. In other words:

<?php
$iterator
= new DirectoryIterator('C:\\');
echo
$iterator->getPathname();
?>

... will NOT print "C:\" but the path of the first file or subdirectory retrieved, e.g. "C:\$Recycle.Bin".
up
4
David Lanstein
15 years ago
DirectoryIterator::getBasename() has been also been available since 5.2.2, according to the changelog (not documented yet).  It takes a parameter $suffix, and is useful if, for instance, you use a naming convention for your files (e.g. ClassName.php). 

The following code uses this to add recursively All*Tests.php in any subdirectory off of tests/, basically, suites of suites.

<?php
// PHPUnit boilerplate code goes here

class AllTests {
    public static function
main() {
       
$parameters = array('verbose' => true);
       
PHPUnit_TextUI_TestRunner::run(self::suite(), $parameters);
    }

    public static function
suite() {
       
$suite = new PHPUnit_Framework_TestSuite('AllMyTests'); // this must be something different than the class name, per PHPUnit
       
$it = new AllTestsFilterIterator(
                  new
RecursiveIteratorIterator(
                      new
RecursiveDirectoryIterator(dirname(__FILE__) . '/tests')));

        for (
$it->rewind(); $it->valid(); $it->next()) {
            require_once(
$it->current());
           
$className = $it->current()->getBasename('.php');
           
$suite->addTest($className::suite());
        }

        return
$suite;
    }
}
?>

Also, the AllTestsFilterIterator above extends FilterIterator, and contains one method, accept():

<?php
class AllTestsFilterIterator extends FilterIterator {
    public function
accept() {
        if (
preg_match('/All.*Tests\.php/', $this->current())) {
            return
true;
        } else {
            return
false;
        }
    }
}
?>
up
-4
Mark van Straten
15 years ago
Implements Iterator so you can foreach() over the content of the given directory
up
-4
Kunal Bhatia->kmasterzone@gmail dot com
12 years ago
Deleting all files in a directory except the one which is last modified.
<?php
    $directory
= dirname(__FILE__)."/demo";
   
$filenames = array();
   
$iterator = new DirectoryIterator($directory);
    foreach (
$iterator as $fileinfo) {
        if (
$fileinfo->isFile()) {
           
$filenames[$fileinfo->getMTime()] = $fileinfo->getFilename();
        }
    }
   
ksort($filenames);
   
print_r($filenames);
    echo
"\n";
   
$i=0;
    if(
sizeof($filenames)>1){
        foreach (
$filenames as $file){
            if(
$i>0){
                echo
$file."\n";
               
unlink($directory."/".$file);
            }
           
$i++;
        }
    }
?>
up
-5
abdel at elghafoud dot com
10 years ago
Shows us recursively all files and catalogues in directory except "." and "..".

<?php

/**
* @param string $directory
* @param array $files
* @return array
*/
public function recursiveDirectoryIterator ($directory = null, $files = array()) {
   
$iterator = new \DirectoryIterator ( $directory );

    foreach (
$iterator as $info ) {
        if (
$info->isFile ()) {
           
$files [$info->__toString ()] = $info;
        } elseif (!
$info->isDot ()) {
           
$list = array($info->__toString () => $this->recursiveDirectoryIterator(
                       
$directory.DIRECTORY_SEPARATOR.$info->__toString ()
            ));
            if(!empty(
$files))
               
$files = array_merge_recursive($files, $filest);
            else {
               
$files = $list;
            }
        }
    }
    return
$files;
}

?>
up
-4
incredimike
6 years ago
For some reason, the `isDot()` method doesn't return positive for the `.DS_Store` file generated by Mac OS's Finder. In practice, I've had to write code to explicitly check for this file:

<?php

foreach (new DirectoryIterator('../moodle') as $fileInfo) {
    if(
$fileInfo->isDot() || $fileInfo->getBasename() === '.DS_Store') continue;
    echo
$fileInfo->getFilename() . "<br>\n";
}

?>
To Top