Working with File Uploads

So far, we've looked at simple form input. However, web browsers support file uploads, and so, of course, does PHP. In this section, you examine the features that PHP makes available to deal with this kind of input.

Information about the uploaded file becomes available to you in the $_FILES super-global, which is indexed by the name of the upload field (or fields) in the form. The corresponding value for each of these keys is an associative array. These fields are described in Table 11.1, using fileupload as the name of the form field used for the upload.

Table 11.1. File Upload Global Variables

Element

Contains

Example

$_FILES["fileupload"]["name"]

Original name of uploaded file

test.gif

$_FILES["fileupload"]["tmp_name"]

Path to temporary file

/tmp/phprDfZvN

$_FILES["fileupload"]["size"]

Size (in bytes) of uploaded file

6835

$_FILES["fileupload"]["type"]

MIME type of uploaded file (where given by client)

image/gif

Keep these elements in the back of your mind for a moment, while we create the upload form in the next section.

Creating the File Upload Form

First, we must create the HTML form to handle the upload. HTML forms that include file upload fields must include an ENCTYPE argument:

ENCTYPE="multipart/form-data"

PHP also works with an optional hidden field that can be inserted before the file upload field. This field must be called MAX_FILE_SIZE and should have a value representing the maximum size in bytes of the file that you're willing to accept. The MAX_FILE_SIZE field is obeyed at the browser's discretion, so you should rely on the php.ini setting, upload_max_filesize, to cap unreasonably large uploads. After the MAX_FILE_SIZE field has been entered, you're ready to add the upload field itself. This is simply an INPUT element with a TYPE argument of "file". You can give it any name you want. Listing 11.13 brings all this together into an HTML upload form.

As you can see, file uploads are limited to 50KB on line 7, and the name of the file upload field is fileupload, as shown on line 8. Save this listing in a text file called fileupload.html and place that file in your web server document root. Use your web browser to access this form and you should see something like Figure 11.9.

Figure 11.9. The form created by Listing 11.13.

This form calls the do_upload.php script, which we will create next.

Creating the File Upload Script

If you remember the information regarding the $_FILES superglobal, you have all the information you need to write a simple file upload script. This script is the back-end for the form created in Listing 11.14.

In Listing 11.14, we first create the $file_dir variable on line 2 to store path information. This path should be one that exists on your system, and the web server user (for example, httpd, www, nobody) must have write permissions for it.

By the Way

The path used in line 2 is a Linux/UNIX path. Windows users would use escaped backslashes, such as:

$file_dir = "C:\\Documents and Settings\\Owner\\Desktop\\";

Line 3 begins a foreach statement that loops through every element in the $_FILES array. A loop is used rather than an if statement to make our script capable of scaling to deal with multiple uploads on the same page. The foreach loop on line 3 stores the upload file's name in the $file_name variable and the file information in the $file_array variable. We can then output the information we have about the upload.

Before moving the uploaded file from its temporary position to the location specified in line 2, first check that it exists. We do so on line 9, using the is_uploaded_file() function. This function accepts a path to an uploaded file and returns true only if the file in question is a valid upload file. This function therefore enhances the security of your scripts.

Assuming that all is well, the file is copied from its temporary home to a new directory on lines 10 and 11. We use another function, move_uploaded_file(), for this purpose. This function copies a file from one place to another, first performing the same security checks as those performed by is_uploaded_file(). The move_uploaded_file() function requires a path to the source file and a path to the destination. It returns true if the move is successful and false if the file isn't a valid upload file or if the file couldn't be found.

Watch Out!

Beware of the names of uploaded files. Operating systems such as Mac OS and Windows are pretty relaxed when it comes to file naming, so expect uploaded files to come complete with spaces, quotation marks, and all manner of other unexpected characters. Therefore, it's a good idea to filter filenames.

Put these lines into a text file called do_upload.php and place that file in your web server document root. Use your web browser to go back to the form and then try to upload a file. If successful, you should see something like Figure 11.10 in your browser.