PHP Scripts and Resources for Webmasters

PHP File Upload Tutorial

This tutorial will demonstrate how to handle file uploads in PHP. We will create a simple XHTML form with a file field, and a PHP script that handles the form submission by moving the uploaded file to a designated directory. This tutorial assumes you are using PHP 4.4.0 or higher.

XHTML for the File Upload Form

The XHTML code for the file field is simply an input field with the type attribute set to "file", and the name attribute set to an arbitrary value. The value provided for the name attribute will be used to identify the uploaded file in our PHP script after the form is submitted. In addition, the containing form tag must have the enctype attribute set to "multipart/form-data" in order for it to work correctly. There is also an optional hidden field for the maximum file size, appropriately named MAX_FILE_SIZE. Note that the MAX_FILE_SIZE parameter can be easily circumvented via a cross-site request forgery. Therefore, the code that handles the uploaded file should always perform a separate check of file size, independent of the MAX_FILE_SIZE parameter.

Below is an example form that can be used to accept the file. This form assumes that the script that will handle the upload is named "upload.php".

<form enctype="multipart/form-data" action="upload.php" 
	method="post">
<input type="hidden" name="MAX_FILE_SIZE" 
	value="50000" />
Select a File:<br />
<input type="file" size="20" name="thefile" /><br />
<input type="submit" name="Submit" value="Submit" />
</form>

PHP Code for the File Upload Handler

Information about the uploaded file is stored in the $_FILES array. The name of the file field on the page determines the key of the uploaded file in this array, e.g. $_FILES['thefile'].

Our PHP code will check the $_FILES array for the key corresponding to the name of the file field in the form we created above. If the key exists, the file upload handling logic will be performed.

if(array_key_exists('thefile', $_FILES)) {
	// Handle the uploaded file here
}

The handler script must check a number of conditions in order to validate the submission. It should confirm that a file was actually selected, that the file does not exceed maximum acceptable size, and that the PHP engine itself did not encounter an error while handling the file.

if(array_key_exists('thefile', $_FILES)) {
// Validate the uploaded file
if($_FILES['thefile']['size'] === 0 
|| empty($_FILES['thefile']['tmp_name'])) {
    echo("<p>No file was selected.</p>\r\n");
} else if($_FILES['thefile']['size'] > 50000) {
    echo("<p>The file was too large.</p>\r\n");
} else if($_FILES['thefile']['error'] !== UPLOAD_ERR_OK) {
    // There was a PHP error
    echo("<p>There was an error uploading.</p>\r\n");
} else {
	// Do the rest of the file handling here
}
}

Each item in the $_FILES array is itself an array representing various attributes of the uploaded file. If a file was not selected for the corresponding field, the "size" item will be zero, and the "tmp_name" item will be empty.

Assuming a successful upload, the "size" item will contain the actual size of the uploaded file in bytes. The "tmp_name" item will contain the name of the temporary file where the upload was saved. The handler script must move the temporary file to another location, otherwise the PHP engine will delete the file upon completion of the request.

The "error" item will contain a code reflecting the status of the upload. If the upload was successful, it will return the constant UPLOAD_ERR_OK. The list of possible error codes can be found in the PHP Manual.

Lastly, our example script must move the uploaded file to another directory. The code below will create a destination directory named "uploads" if it does not exist, and call the PHP function move_uploaded_file() to move the file to that directory.

if(array_key_exists('thefile', $_FILES)) {
// Validate the uploaded file
if($_FILES['thefile']['size'] === 0 
|| empty($_FILES['thefile']['tmp_name'])) {
    echo("<p>No file was selected.</p>\r\n");
} else if($_FILES['thefile']['size'] > 50000) {
    echo("<p>The file was too large.</p>\r\n");
} else if($_FILES['thefile']['error'] !== UPLOAD_ERR_OK) {
    // There was a PHP error
    echo("<p>There was an error uploading.</p>\r\n");
} else {
// Create uploads directory if necessary
if(!file_exists('uploads')) mkdir('uploads');
// Move the file
if(move_uploaded_file($_FILES['thefile']['tmp_name'], 
'uploads/' . $_FILES['thefile']['name'])) {
    echo("<p>File uploaded successfully!</p>\r\n");
} else {
    echo("<p>There was an error moving the file.</p>\r\n");
}
}
}

Make sure to use the move_uploaded_file() function rather than one of the general purpose file handling functions, as this function will perform a security check to confirm that the specified file is in fact a valid uploaded file.

Hopefully this tutorial has given you a good idea of how file uploads are handled in PHP. Please note that this simple example code is provided for learning purposes only. When allowing uploads on a public website, you would probably want to add some form of authorization, and filter the types of files being uploaded.

Back to Tutorials