April 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Uploading Files within a PHP Script

  • September 3, 2002
  • By Elizabeth Fulghum
  • Send Email »
  • More Articles »

Being able to accept uploads from your users is one of those surprisingly essential functions that re-occur in many applications. Examples are everywhere: on bulletin boards people are often allowed to upload attachments and custom avatars, content management systems allow administrators to upload images for posts and web site management scripts utilize uploads to give users to ability to edit and add new files.

Adding file uploads to your own scripts is relatively easy. Because HTML includes a file upload form field: <input type="file" name="file"> the client side task of selecting a file is handled for you by the browser.

When including a file upload field in a form, an additional attribute also must be added to the form tag: enctype="multipart/form". This tells the browser that in addition to the standard text, a file may be send with the form. Also, the form method should always be POST rather than GET for the file to be sent.

Pay particular attention to the form tag and file input field as we take a look at a simple page containing a form:

<html>
<head></head>
<body>

<form action="<?=$PHP_SELF?>" method="post" enctype="multipart/form-data">
<br><br>
Choose a file to upload:<br>
<input type="file" name="file"><br>
<input type="submit" name="submit" value="submit">
</form>

</body>
</html>

If the user selects a file and submits the form, then the file will be uploaded and stored in a temporary directory on the server with a temporary name. This is when the real programming begins.

Accessing Uploaded Files

Just like other form elements, the value of the file field can be accessed by with the variable name that matches the name of the input; in this case "file". Unlike other form variables though, variables that reference uploaded files are arrays, and contain additional useful information:

$HTTP_POST_FILES['file']

the parent array, where 'file' is the name of the file input field in the form.
$HTTP_POST_FILES['file']['name'] the original name of the file from the user's computer.
$HTTP_POST_FILES['file']['tmp_name'] the temporary name assigned to the file when its uploaded.
$HTTP_POST_FILES['file']['type'] the mime type of the file, as provided by the user's browser
$HTTP_POST_FILES['file']['size'] the size of the file, in bytes.

Validation

Include a reminder on your form telling users that they should only upload gif files under 10kb, and you can bet that a good half of them will try to upload 10mb executable files. It is for this reason that validating uploaded files is particularly important.

Typically, there are three checks that should be performed on incoming files:

1.) that a file was actually uploaded. If one was...
2.) that it is under under a specified file size and...
3.) that it's file type is one of those that you want to accept.

A few if statements is all that is needed to perform this type of validation, and even create some friendly error messages to display to the user in case of one the checks fails. Let's take a look at how it can be done.

There are several ways to see whether a file has been uploaded, depending on which version of PHP you use. The most secure and accurate way is with is_uploaded_file(), available in versions of PHP3, and PHP4.0.2 and higher:

if (!is_uploaded_file($HTTP_POST_FILES['file']['tmp_name'])) {
  $error = "You did not upload a file!";
  unlink($HTTP_POST_FILES['file']['tmp_name']);
} else {
  //a file was uploaded
}

The if statement checks to see if a temporary file was created with the specified name and if so, that it is an uploaded file. If you want to require the user to upload a file, you can create a variable to hold an error message, and stop processing the form entirely at this point. If a file has been uploaded, then the contents of the else statement will execute. This is where all of the other error checking a processing for the file should be nested, so that the next block of error checking code only executes if upload has passed the first.

The next thing we need to validate is the size of the file. For the purposes of this example, let's say that you wanted to only allow files under 10kb. First, we'll assign the maximum allowed file size to a variable (in bytes), then check it against the actual size of the uploaded file (in bytes):

$maxfilesize=10240;

if ($HTTP_POST_FILES['file']['size'] > $maxfilesize) {
  $error = "file is too large";
  unlink($HTTP_POST_FILES['file']['tmp_name']);
} else {
  //the file is under the specified number of bytes.
}

Again, if the uploaded file fails the check, we will generate an error message and stop processing the form. In addition, because a file was successfully uploaded, we need to remove it from the server in case of an error using the unlink() function.

The final check performed on the file is to validate the file type. You might consider doing this by checking the extension of the filename the user uploaded. The problem with this method is that file names can be altered; the user could easily rename an .exe file to have a .jpg extension, and no one would be the wiser.

For a little more secure file type detection, we can make use of the $HTTP_POST_FILES['file']['type'] variable, which contains the (harder to alter) mime-type of the file. In this example, we will just check to make sure the file is a jpg or gif:

if($HTTP_POST_FILES['file']['type'] != "image/gif" AND $HTTP_POST_FILES['file']['type'] != "image/pjpeg" AND $HTTP_POST_FILES['file']['type'] !="image/jpeg") {
  $error = "This file type is not allowed";
  unlink($HTTP_POST_FILES['file']['tmp_name']);
} else {
   //the file is the correct format
}

Again, if our validation fails, we assign an error message and remove the uploaded file. If it is successful, this point, we can copy it to its final destination; giving it a new name, or using the original one from the user's computer:

copy($HTTP_POST_FILES['file']['tmp_name'],"/finallocation/".$HTTP_POST_FILES['file']['name']);

And after the file has been copied to its final location, we can remove the temporary file:

unlink($HTTP_POST_FILES['file']['tmp_name']);

To make sure that the code to handle the upload only executes when the form is actually submitted, the entire block is wrapped up within an if statement that check to see if the submit button has been pressed. Take a look at the entire script:

<?php

if ($HTTP_POST_VARS['submit']) {
  print_r($HTTP_POST_FILES);
  if (!is_uploaded_file($HTTP_POST_FILES['file']['tmp_name'])) {
    $error = "You did not upload a file!";
    unlink($HTTP_POST_FILES['file']['tmp_name']);
    // assign error message, remove uploaded file, redisplay form.
  } else {
    //a file was uploaded
    $maxfilesize=10240;

    if ($HTTP_POST_FILES['file']['size'] > $maxfilesize) {
      $error = "file is too large";
      unlink($HTTP_POST_FILES['file']['tmp_name']);
      // assign error message, remove uploaded file, redisplay form.
    } else {
      if ($HTTP_POST_FILES['file']['type'] != "image/gif" AND $HTTP_POST_FILES['file']['type'] != "image/pjpeg") {
        $error = "This file type is not allowed";
        unlink($HTTP_POST_FILES['file']['tmp_name']);
        // assign error message, remove uploaded file, redisplay form.
      } else {
       //File has passed all validation, copy it to the final destination and remove the temporary file:
       copy($HTTP_POST_FILES['file']['tmp_name'],"/finallocation/".$HTTP_POST_FILES['file']['name']);
       unlink($HTTP_POST_FILES['file']['tmp_name']);
       print "File has been successfully uploaded!";
       exit;
     }
    }
  }
}
?>

<html>
<head></head>
<body>
<form action="<?=$PHP_SELF?>" method="post" enctype="multipart/form-data">
<?=$error?>
<br><br>
Choose a file to upload:<br>
<input type="file" name="file"><br>
<input type="submit" name="submit" value="submit">
</form>
</body>
</html>

To stop the script from redisplaying the form after a successful upload has been completed, we add a message letting the user know that the file has been accepted, and exit the script. You can also easily add a header redirection command here to move to another page or perform any additional form validation.

If the upload was unsuccessful, the form will automatically redisplay. An added PHP line within the form HTML to output the error will provide details the user explaining why the file was not accepted.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel