Team LiB
Previous Section Next Section

File Access Support Functions

Along with the generalized functions for dealing with file and directory manipulation we have discussed thus far, the life of the PHP developer is also further simplified through the addition of a wide range of file-system support functions. These functions in general could be built using pure PHP, using the tools discussed earlier in this chapter. However, instead of making you (the developer) do such work yourself, PHP offers many of these common tasks natively.

Note that the following functions are by no means a complete reference to all the supporting file system functions available in PHP. For further information on both these functions and those not discussed, consult the PHP Manual available at http://www.php.net/manual/.

Logic Functions

Of all the support functions we'll discuss in this section, the first that we will look at are the file-system logic functions. These functions are logic functions because they are all designed to test a property of a file (if it is executable, if it is a directory, and so on) and return a Boolean TRue or false. Because of the closely related nature (and simplicity) of most of these functions, I'll be forgoing much of the explanation that would normally be taking place.

The one important point to make regarding the following functions is that they apply only to files in the "local" file system. This means that although they should work on network mounted or shared directories, they will not work on files on a remote server that must be accessed via HTTP or FTP.

As I have alluded, most of the functions that are considered "logic" functions are used to determine a particular property of the provided file. Specifically, PHP provides the following logic functions to determine properties of a given file, as shown in Table 20.6. Each of these functions accepts a single parameter (the filename to check) and returns a Boolean value determining whether the file has the requested property:

Table 20.6. PHP File Logic Functions

is_dir()

Determines if the file is a directory.

is_executable()

Determines if the file is executable by PHP.

is_file()

Determines if the filename is an actual file or a symbolic link to a file (returns true if a real file).

is_link()

Determines if the file is a symbolic link or an actual file (opposite of is_file()).

is_readable()

Determines if PHP is able to read from the given file.

is_uploaded_file()

Determines if the given file was uploaded to the server via the Web server.

is_writeable()

Determines if PHP is able to write to the given file.

file_exists()

Determines if the given file exists.


In practice, this family of logic functions is extremely easy to use, as shown in Listing 20.14, which displays the properties of a given file:

Listing 20.14. Using the File-System Logic Functions
<?php
     $testfile = "/tmp/myfile.dat";
     if(!file_exists($testfile)) {
          echo "Error -- $testfile doesn't exist!<BR>";
          exit;
     }
     echo "What we know about the file $testfile<BR>";
     if(is_dir($testfile)) echo "It is a directory.<BR>";
     if(is_file($testfile)) echo "It is an actual file (not symbolic link)<BR>";
     if(is_link($testfile)) echo "It is a symbolic link to a real file<BR>";
     if(is_uploaded_file($testfile)) echo "It is an uploaded file<BR>";
     if(is_readable($testfile)) echo "The file is readable by PHP<BR>";
     if(is_writeable($testfile)) echo "The file is writeable by PHP<BR>";
     if(is_executable($testfile)) echo "The file is executable by PHP<BR>";
?>

File Manipulation

During the course of this chapter, you have been introduced to using PHP to read and write data to files using the fopen() family of functions. However, with what has been learned, there is still no method available for general file manipulations, such as deleting files, creating symbolic or hard links to files (Unix environments only), or copying files. This section will be discussing how such tasks are accomplished using PHP.

Although you can duplicate most of the functions (for instance, copying a file) that are discussed in this section yourself, using PHP, there has yet to be a method provided for deleting a file. In PHP, deleting a file is accomplished via the use of the unlink() function. The syntax for unlink() is as follows:

unlink($filename)

$filename represents the file to delete from the file system. When executed, the unlink() function returns a Boolean value indicating the success or failure of the deletion. As was indicated in the earlier section in this chapter on permissions, when running PHP in an Unix environment, the user under which PHP runs must have write permissions for the file to delete. The following example uses the unlink() function in tangent with glob() (discussed earlier in the section about directories) to remove all files that end in .tmp from the /tmp/ directory (see Listing 20.15):

Listing 20.15. Using the unlink() Function
<?php

     $files = glob("/tmp/*.tmp");

     foreach($files as $val) {
               unlink($val);
     }
?>

Another rotationally useful function available when working with files is the copy() function. As its name implies, this function will copy a given source file into a new location (or another filename), leaving the source file intact. The syntax for the copy() function is as follows:

copy($source_file, $dest_file)

$source_file represents the source path and file to copy and $dest_file represents the path and new filename of the destination file. The copy() function returns a Boolean value indicating whether the file was successfully copied. In Listing 20.16, this function is used with the unlink() function to create a function move(), which moves a file instead of just copying it:

Listing 20.16. Using the copy() Function
<?php
     function move($source, $dest) {
          if(!copy($source, $dest)) return false;
          if(!unlink($source)) return false;
          return true;
     }

     if(!move("/tmp/myfile.txt", "/tmp/tmpdir/newfile.txt")) {
                    echo "Error! Couldn't move the file!<BR>";
     }
?>

In Listing 20.16, the copy() function was used to create the move() function. PHP provides a special function to be used when moving files uploaded to the Web server via HTTP (see Chapter 4, "Working with Forms in PHP," for information on uploading files via HTTP). This function does more than just move the uploaded file. It also checks to ensure that the file you are attempting to move is the file that was uploaded. This is to combat a potential security issue by ensuring as much as possible that the uploaded file your PHP script works with is indeed the file that was uploaded. This function is called move_uploaded_file() and has the following syntax:

move_uploaded_file($filename, $destination)

$filename is the name of the file uploaded via HTTP to move, and $destination represents the complete path and new filename in which to move the file. The example shown in Listing 20.17 assumes that a file has been uploaded via HTTP (POST method) under the name myupload:

Listing 20.17. Using the move_uploaded_file() Function
<?php
     /* Assumed that the file has been uploaded via HTTP POST */
     $tmp_filename = $_FILES['myupload']['tmp_name'];
     if(!move_uploaded_file($tmp_filename,
         "/path/to/dest/{$_FILES['myupload']['name']}")) {

          echo "An error has occurred moving the uploaded file.<BR>";
          echo "Please ensure that if safe_mode is on that the " .
               "UID PHP is using matches the file.";
          exit;
     } else {
          echo "The file has been successfully uploaded!";
     }
?>

Specialized File Access

To wrap up the chapter on file-system access from PHP, let's take a look at a few "specialty" functions that can greatly simplify certain file-related tasks. The first function that I'll discuss is the readfile() function.

At times, it is desirable to take a file (usually text based) and dump the file in its entirety to the client. To simplify this task, PHP provides the readfile() function using the following syntax:

readfile($filename [, $use_include_path])

$filename represents the filename (local or remote using URL wrappers) to dump to the client, and $use_include_path is a Boolean value determining whether the file should be searched for in the PHP include path. In Listing 20.18, we use the readfile() function to load the file agreement.txt into a <TEXTAREA> HTML tag:

Listing 20.18. Using the readfile() Function
<HTML><HEAD><TITLE>Using the readfile() function</TITLE></HEAD>
<BODY>
<TEXTAREA ROWS=5 COLS=60 NAME="agreement">
<?php readfile("agreement.txt"); ?>
</TEXTAREA>
</BODY>
</HTML>

Along with the readfile() function (which dumps the contents of a file directly to the client), PHP also provides the means to read an entire file (binary-safe) into a PHP variablethe file_get_contents() function. The syntax for the file_get_contents() function is identical to that of the readfile() function:

file_get_contents($filename [, $use_include_path])

Like readfile(), $filename represents the name of the file (local or remote via URL wrappers) to load, and $use_include_path represents a Boolean value indicating whether the file should be searched for in the PHP include path. Upon success, file_get_contents() returns a binary-safe string containing the contents of the entire file. If file_get_contents() cannot find or read the contents of the file, the function will return false. In Listing 20.19, file_get_contents() is used to load agreement.txt into a string and convert the entire contents of the file to uppercase prior to displaying it to the client:

Listing 20.19. Using the file_get_contents() Function
<HTML><HEAD><TITLE>Using the file_get_contents() function</TITLE></HEAD>
<BODY>
<TEXTAREA ROWS=5 COLS=60 NAME="agreement">
<?php
      $agreement = file_get_contents("agreement.txt");
      $agreement = strtoupper($agreement);
      echo $agreement;
?>
</TEXTAREA>
</BODY>
</HTML>

Although the file_get_contents() function is useful, there is a second (and third, really) flavor of the same function to use depending on your needs. For instance, if you would like to read a given text-based file into an array, the file() function can be used. The syntax of the file() function is as follows:

file($filename [, $use_include_path])

$filename represents a file (either local or remote using URL wrappers) to read, and $use_include_path represents a Boolean value determining whether the PHP include path should be searched. Upon success, file() returns an array representing each individual line within the text file (newline character still attached). If the file() function fails to open and read the contents of the file into an array, it returns a Boolean false. In Listing 20.20, the file() function is used to read from one of the text-based adage lists provided by the Unix fortune program and then pick a random one to display to the client:

Listing 20.20. Using the file() Function
<?php

     $fortune = "/usr/share/games/fortune/men-women";
     $sayings = file($fortune);
     $dump = false;

     if(!$sayings) {
        echo "Error -- Couldn't open the fortune file!";
        exit;
     }
     srand((double)microtime() * 1000000);
     $start = rand(0, count($sayings));

     for($i = $start; $i < count($sayings); $i++) {

        if($sayings[$i] == "%\n") {

                if($dump) exit;
                $dump = !$dump;
                $i++;
        }

        if($dump) echo $sayings[$i];
     }

?>

To understand how Listing 20.20 works, you have to have a little information on the structure of the fortune program data files. In the data files, each adage is separated by a % symbol on its own line. In the preceding example, we start from a random line in the file and process the file line-by-line starting from this point until the first adage break is encountered. At this point, the $dump flag is then set to true and all the lines past that point are dumped to the client until another % is encountered, at which point the script exits.

    Team LiB
    Previous Section Next Section