PHP File Uploading Best Practice

PHP Best Practices

Novice level help for uploading files to a remote system utilizing best methods of PHP.


Date : 2006-02-17
PHP File Uploading Best Practice

Rafe Magnuson 02-17-2006

For the novice, uploading files using PHP can be a daunting experience. In this article we will hopefully be able to lift the haze that surrounds the subject and provide a roadmap to easier use of this powerful functionality.

There are two basic pieces to the upload process that will be covered here. The form that will be used to post the file data to and the actual program that does the uploading. Further we will discuss the method that PHP.NET itself suggests for uploading multiple files.

The html form that is required to allow user input can be one of the most frustrating pieces of this process in that if the data encoding type is not specified clearly then no matter how well programmed the upload piece is the entire process will not work. The base method for creating a form that adheres to the correct coding type is as follows:





Code:
<form enctype="multipart/form-data" action="__URL__" method="POST">
   <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
   Upload a file: <input name="somefile" type="file" />
   <input type="submit" value="Upload" />
</form>


Note the enctype is set to "multipart/form-data". This is crucial to the working of the application. If it is not specified here then the program will not work. Simple as that.

Next you'll notice that MAX_FILE_SIZE precedes the file input field. The MAX_FILE_SIZE for this demonstration is limited to 30000 bytes, or about 29K, but can easily be modified for larger files.

Finally you have the input sections. The first is set to create an input box that allows the user to choose his file and the second is the button that actually submits the file for upload. In the next section you'll notice that the name of the input element for type="file" will be used to determine the name to pull from the $_FILES array.

So now you have your input form allowing for the selection of a file of approximately 29K and the means to upload it through the use of a submit button that will call POST.

Now we will look at the code to do the actual upload. It appears like this:

Code:
<?php
  $uploaddir = '/uploads/';
$uploadfile = $uploaddir . basename($_FILES['somefile']['name']);
if (move_uploaded_file($_FILES['somefile']['tmp_name'], $uploadfile)) {
   echo "File successfully uploaded.n";
} else {
   echo "Upload failedn";
}
?>


Looks simple enough, right? Well, lets disect it a line at a time.

Line 1 of course just declares that we're using php, but we knew that already.
Line 2 declares the directory where we want the file to get to once we're finished. This should always be a writeable directory on your server, otherwise nothing will be uploaded and we'll get an error.
Line 3 combines the upload directory with the file that we are uploading into a single string called $uploadfile.
At line 4 is where things get interesting. At this time we check to see if the file in $uploadfile is actually valid and then upload it if it is. Note that the upload actually takes place in two steps internally. First it uploads the file to a temporary directory and then it actually moves the file to its final locaton. This is all handled in one fell swoop by using the move_uploaded_file command. Also, be aware that although most servers run a recent version of php that this will not work with any version of php less than 4.1.

The final lines are just notifications depending on what happened during the transfer process. If everything went according to plan you would get a "File successfully uploaded." message and the program would quit, otherwise you would get the error in line 7.

One way of checking yourself if you have a problem with file uploading in this manner is to analyze the $_FILES array. This can be done by simply adding this line

Code:
print_r($_FILES);


at some relative point in the code. Usually this is best to be done for debugging purposes only and a good place to put it might be in the else clause.

Uploading multiple files is just about as easy except that we need to include a loop to upload each file within the array that gets passed.

Code:
<form action="" method="post" enctype="multipart/form-data">
<p>Three Files:
<input type="file" name="myfile[]" />
<input type="file" name="myfile[]" />
<input type="file" name="myfile[]" />
<input type="submit" value="Send" />
</p>
</form>

<?php
    foreach ($_FILES["myfile"]["error"] as $key => $error) {
      if ($error == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["myfile"]["tmp_name"][$key];
        $name = $_FILES["myfile"]["name"][$key];
        move_uploaded_file($tmp_name, "data/$name");
      }
    }
?>


So again we have the form where a user can add up to three files to be uploaded and then we have the php portion of the code which loops through the $_FILES array and for each entry found the file is checked to make sure there are no errors and then uploaded/moved to the specified directory.

Note that to check for errors in the uploading of these multiple files the code looks at the $error variable. The error variable contains a human-readable value which in this case is hoped to be UPLOAD_ERR_OK but if there is a problem can be any of 7 messages including:

Code:
UPLOAD_ERR_OK - Value: 0; There is no error, the file uploaded with success.
UPLOAD_ERR_INI_SIZE - Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.
UPLOAD_ERR_FORM_SIZE - Value: 2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
UPLOAD_ERR_PARTIAL - Value: 3; The uploaded file was only partially uploaded.
UPLOAD_ERR_NO_FILE - Value: 4; No file was uploaded.
UPLOAD_ERR_NO_TMP_DIR - Value: 6; Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3.
UPLOAD_ERR_CANT_WRITE - Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0.


In conclusion, any long-time PHP programmer can find ways to make the afore-metioned code more robust and even more secure for any given purpose, but it is hoped that this walk though has provided a good stepping off point for those junior PHP programmers who have a need for uploading files.

Comments :

No comments yet
  • Search For Articles