Reading through a directory with PHP

Posted in PHP -

PHP's opendir() readdir() and closedir() are used for reading the contents of a directory (there's also glob() and scandir() but I'll cover those in later posts). Combined with functions like is_file() is_dir() and is_link() and you can easily build up a directory tree or process files etc.

Example directory

The examples below look at a directory with the following:

bar.txt       A regular file
baz           A directory
foo.txt       A regular file
link2foo.txt  A symbolic link to foo.txt

Simple example

A simple example to loop through the directory's contents and display the names of the files, directories etc within it is as follows:

$handle = opendir("/path/to/directory");
while($name = readdir($handle)) {
    echo "$name\n";
}
closedir($handle);

The output for the example directory is:

foo.txt
..
bar.txt
.
baz
link2foo.txt

Note that it's not sorted in any particular way and includes . and .. which are indicators for the current directory and parent directory.

Sorting the data

Instead of echoing out the filenames they could instead be stored in an array, sorted and then some other processing done on them. This will ensure they are in alphabetical order.

$handle = opendir("/path/to/directory");
$names = array();
while($name = readdir($handle)) {
    $names[] = $name;
}
closedir($handle);
sort($names);

Doing print_r($names) will show this:

Array
(
    [0] => .
    [1] => ..
    [2] => bar.txt
    [3] => baz
    [4] => foo.txt
    [5] => link2foo.txt
)

Testing what type of file it is

The final example loops through the directory and checks whether it's a file, directory or symbolic link and does some processing depending on which type it is (in this example it's simply echoing out what type it is and the name). The additional if($name != '.' && $name != '..') text excludes the special . and .. directory names.

$dir = "/path/to/dir";
$handle = opendir($dir);
while($name = readdir($handle)) {
    if(is_dir("$dir/$name")) {
        if($name != '.' && $name != '..') {
            echo "directory: $name\n";
        }
    }
    elseif(is_link("$dir/$name")) {
        echo "link: $name\n";
    }
    else {
        echo "file: $name\n";
    }
}
closedir($handle);

And the output:

file: foo.txt
file: bar.txt
directory: baz
link: link2foo.txt

Next posts in this series

To follow up this post I'll look at using scandir() and glob().



Related posts:


Comments