Working with Directories

Now that you can test, read, and write to files, let's turn our attention to directories. PHP provides many functions for working with directories. Let's look at how to create, remove, and read them.

Creating Directories with mkdir()

mkdir() enables you to create a directory. mkdir() requires a string that represents the path to the directory you want to create, and an octal number integer that represents the mode you want to set for the directory. You specify an octal (base 8) number with a leading 0. The mode argument has an effect only on Unix systems. The mode should consist of three numbers between 0 and 7, representing permissions for the directory owner, group, and everyone, respectively. mkdir() returns true if it successfully creates a directory, or false if it doesn't. If mkdir() fails, it's usually because the containing directory has permissions that preclude processes with the script's user ID from writing. If you're not comfortable setting Unix directory permissions, you should find that one of the following examples fits your needs. Unless you really need your directory to be world writable, you should probably use 0755, which allows the world to read your directory but not to write to it.

mkdir("testdir", 0777); // global read/write/execute permissions
mkdir("testdir", 0755); // world and group: read/execute only
                        // owner: read/write/execute

Removing a Directory with rmdir()

rmdir() enables you to remove a directory from the file system if the process running your script has the right to do so and if the directory is empty. rmdir() requires only a string representing the path to the directory you want to create.


Opening a Directory for Reading with opendir()

Before you can read the contents of a directory, you must first obtain a directory resource. You can do so with the opendir() function. opendir() requires a string that represents the path to the directory you want to open. opendir() returns a directory handle unless the directory isn't present or readable; in that case, it returns false.

$dh = opendir("testdir");

Reading the Contents of a Directory with readdir()

Just as you use gets() to read a line from a file, you can use readdir() to read a file or directory name from a directory. readdir() requires a directory handle and returns a string containing the item name. If the end of the directory is reached, readdir() returns false. Note that readdir() returns only the names of its items, rather than full paths. Listing 10.14 shows the contents of a directory.

Listing 10.14 Listing the Contents of a Directory with readdir()
  1: <html>
  2: <head>
  3: <title>Listing 10.14 Listing the contents
  4: of a directory with readdir()</title>
  5: </head>
  6: <body>
  7: <?php
  8: $dirname = ".";
  9: $dh = opendir($dirname) or die("couldn't open directory");
 11: while (!(($file = readdir($dh)) === false)) {
 12:     if (is_dir("$dirname/$file")) {
 13:            print "(D) ";
 14:      }
 15:      print "$file<br>";
 16: }
 17: closedir($dh);
 18: ?>
 19: </body>
 20: </html>

If this code were saved to the document root of your Web server and run through your Web browser, the output could look something like Figure 10.7.

Figure 10.7. Output of Listing 10.14.


We open our directory for reading with the opendir() function on line 9 and use a while statement to loop through each of its elements on line 11. We call readdir() as part of the while statement's test expression and assign its result to the $file variable. Within the body of the while statement, we use the $dirname variable in conjunction with the $file variable to create a full file path, which we can then test on line 12. If the path leads to a directory, we print ("D") to the browser on line 13. Finally, we print the filename on line 15.

We used a cautious construction in the test of the while statement. Most PHP programmers (myself included) would use something like the following:

while ($file = readdir($dh)) {
      print "$file<BR>\n";

The value returned by readdir() is tested. Because any string other than "0" resolves to true, there should be no problem. Imagine, however, a directory that contains four files: "0", "1", "2", and "3". On my system, the output from the preceding code is as follows:


When the loop reaches the file named "0", the string returned by readdir() resolves to false, which causes the loop to end. The approach in Listing 10.14 uses === to check that the return value returned by readdir() is not exactly equivalent to false. 0 only resolves to false in the test, so we circumvent the problem.


If you find the ordering of items in a directory listing to be arbitrary, it's because the order is determined by the file system. If you want the items ordered in a specific fashion, you must read the contents into an array, which can then be sorted to your liking and subsequently displayed.

    Part III: Getting Involved with the Code