Working with Directories
Now that you can test, read, and write to files, turn your attention to directories. PHP provides many functions to work with directories. You will look at how to create, remove, and read them.
Creating Directories with mkdir()
mkdir() enables you to create a directory. mkdir() requires a string representing the path to the directory you want to create and an integer that should be an octal number representing the mode you want to set for the directory. You specify an octal (base 8) number with a leading 0. The mode argument will only have an effect on Unix systems. The mode should consist of three numbers between 0 and 7, representing permissions for the directory owner, group, and everyone, respectively. This function returns true if it successfully creates a directory, or false if it doesn't. If mkdir() fails, this will usually be because the containing directory has permissions that preclude processes with the script's user ID from writing. If you are not comfortable with setting Unix directory permissions, you should find that one of the examples below 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 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.
rmdir( "testdir" );
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 this with the opendir() function. opendir() requires a string representing the path to the directory you want to open. opendir() returns a directory handle unless the directory is not present or readable, in which 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 has been 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"); 10: 11: while ( ! ( ( $file = readdir( $dh ) ) === false ) ) { 12: if ( is_dir( "$dirname/$file" ) ) 13: print " "; 14: print "$file<br>"; 15: } 16: closedir( $dh ); 17: ?> 18: </body> 19: </html>
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, assigning 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 " " to the browser on line 13. Finally, we print the filename on line 15.
We have 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() will be tested. Because any string other than "0" will resolve to true, there should be no problem. Imagine, however, a directory that contains four files, "0", "1", "2", and "3". The output from the preceding code on my system is as follows:
. ..
When the loop reaches the file named "0", the string returned by readdir() resolves to false, causing 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.