In this tutorial we’ll be creating a basic File Upload System. This tutorial only requires you (preferably) to have a basic understanding about PHP variables and loops. Although, some pre-knowledge about PHP arrays wouldn’t hurt either!
Overview
Let’s start with having a look at the functions that will be explained in this tutorial and so our file upload system will be cappable of:
- Upload form
- Uploading files to a specific directory
- Set max file size for upload files
- Limit uploadable files by specific file extension
- Retrieve error message & handling
- Check whether file doesn’t already exists
Upload Form
We’ll start off with creating a upload form for our file upload system. File upload systems often use the POST method for this form which is a common way of submitting data using forms. The action of the form is set to the file that will handle the uploading, which will be done in the same file: “upload.php”. One last thing that we’ll need to set for our form is the enctype attribute which we set to “multipart/form-data”. This will basicly enable us to upload files and handle them.
Allright, now we ll be adding the fields to the form. Which are the ’select upload file’ input field and the ’submit’ button. Let’s start with the ’select upload file’ input field. This input field allows the user to pick a file to upload. It can be created by creating a normal input field in which you set the type equal to ‘file’. This will make it a common file select input field in which the user can select a file from his computer to upload. Give it any name you like but remember we’ll need the name of the input field later to retrieve the file selected by the user ( and all data related to it ). Here I gave it the name ‘uploadfile’.
The second input field we’ll be adding is the submit button. Which we can create by adding a normal input field with as type set to ’submit’. The value of this input field will be shown as text on the button. Also don’t forget to set a name for this input field ( submit button ) as otherwise no POST data will be send which is required to check if the form was submitted.
File: upload.php
That’s it, our basic file upload form. However notice that we’ll be editing it later by adding more input fields to it which allow us to set more limitations or use more features of file handling system.
File Upload Handling
Okay, so we’ve now got our basic file uploading form in which the user can select a file to upload and submit it. But obviously this doesn’t do the job of actually uploading the file selected by the user. Therefore we’ll need to use some PHP functions, handle the uploading process. All info we need about the user selected upload file and the process of submiting it can be found inside the array variable $_FILES['file_inputfield_name']. And as in the example we gave the ‘file’ input field the name ‘uploadfile’, we can find all file data in $_FILES['uploadfile']. So what data can be found inside? Here’s a basic list of the sub-variables we’ll be using:
[TABLE=3]
The first thing we want to do is check whether any error occured already while ’submitting’ the file (through form). To do this we’ll check the ‘error’ subvariable which is stored in $_FILES['uploadfile']['error'] assuming the upload file input field is given the name ‘uploadfile . You can as well see this in the table above. When no errors have occured, this variable should contain the numeric value ‘0′. So to check if any errors occured we simply check it with an if loop:
<?php
if($_FILES['uploadfile']['error'] > 0) {
echo "Error occured!";
}else{
//... no error occured - upload the file! ...
}
?>
This needs to be checked once the file has been ( attempted to be ) submitted. This can be checked by checking the array variable $_POST. As we used the method ‘POST’ for submitting the form data. Which means that, once the form has been submitted, all data will go inside the $_POST array variable. So we simply check if this is the case by using the empty function to check whether it’s empty. We put a ! before it to check if it is NOT empty ( so if the form has been submitted ).
<?php
if(!empty($_POST)) {
if($_FILES['uploadfile']['error'] > 0) {
echo "Error occured!";
}else{
//... no error occured - upload the file! ...
}
}
?>
Let’s put it together with the form:
File: upload.php
<?php if(!empty($_POST)) { if($_FILES['uploadfile']['error'] > 0) { echo "Error occured!"; }else{ //... no error occured - upload the file! ... } } ?>
Now we’re heading to the part of processing the uploading of the file. Therefore we can use a simple function move_uploaded_file. Which, when we put it in a loop, does 2 things for us: checking whether the file could be uploaded to a temporary directory AND ( if so ) move the uploaded file to our set directory. So it will require us to set 2 argruments for it, the upload file and the path to move the uploaded file to. The path will need to include the name of the file too ($_FILES['uploadfile']['name'])!
$path = "uploads/".$_FILES['uploadfile']['name'];
We create a variable $path which we put the path for the upload file to be moved to, into. We set it to ‘uploads/uploadfile_name’ but you can set it to any directory you like the upload file to be placed into.
Now, the function to actually move the uploaded file to this path looks like this:
move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path);
As the $_FILES['uploadfile']['tmp_name'] is the path of the temporary location in which the upload file was automaticly uploaded into and the $path variable contains the path that it needs to be moved to.
And inside a loop:
if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path)) {
//... file successfully uploaded and moved to the path set in $path
}else{
//... could not move uploaded file to path set in $path
}
Let’s put it inside our script:
File: upload.php
<?php if(!empty($_POST)) { if($_FILES['uploadfile']['error'] > 0) { echo "Error occured!"; }else{ //... no error occured - upload the file! ... //>>>>HERE<<<<< $path = "uploads/".$_FILES['uploadfile']['name']; if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path)) { //... file successfully uploaded and moved to the path set in $path echo "File <b> ".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$path; }else{ //... could not move uploaded file to path set in $path echo "Error - could not move uploaded file to {$path}!"; } } } ?>
We put it in the second loop which checks if there were any errors ( remember? ) and we put it in the else part which is executed when no errors were found. As in that case the file was successfully submitted and uploaded to temporary path, and needs to be uploaded/moved to the definitive path.
Max File Size
For adding a max file size we could either do this inside the php.ini file (find MAX_FILE_SIZE) or by adding another input field to the form. You could even make another loop to check if the max file size was not exceeded (check $_FILES['uploadfile']['size'] to check ). However we’ll be using the second method: we’ll add another input field to the file upload form. This input field needs to be hidden as it just sets a value, and is not litterally an input field. We need to set the name of the input field equal to ‘MAX_FILE_SIZE’ so the system will recognize it as the input field containing the max file size for the upload file.
The type of the field is set to ‘hidden’ as mentioned above already. The name to ‘MAX_FILE_SIZE’, also as mentioned above and the value to ‘1048576′ BYTES, which is equal to 1 MB (1024 bytes = 1 KB, 1024 KB = 1 MB => 1 MB = 1024 BYTES * 1024 = 1048576 BYTES (1 MB) ).
Add it to the form with the other input fields and … <b>DONE!</b>
File: upload.php
<?php if(!empty($_POST)) { if($_FILES['uploadfile']['error'] > 0) { echo "Error occured!"; }else{ //... no error occured - upload the file! ... //>>>>HERE<<<<< $path = "uploads/".$_FILES['uploadfile']['name']; if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path)) { //... file successfully uploaded and moved to the path set in $path echo "File <b> ".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$path; }else{ //... could not move uploaded file to path set in $path echo "Error - could not move uploaded file to {$path}!"; } } } ?>
Upload File Extensions
Now we’ll be creating another loop to check whether the extension of the uploaded file is allowed by us. In this example we’ll allow a couple of image types (jpg, jpeg, gif, png and bmp) but make it anything you want to allow upload files of. The extension of the upload file is set in $_FILES['uploadfile']['type'] as explained in the beginning of this tutorial inside the table, list. We’ll use a simple pattern to check if the file type, extension, is any of these images. If you aren’t familiar with php patterns either skip this part, use a regular if loop or have a look at the tutorial about user input validation.
/^image\/(jpg|jpeg|gif|png|bmp)$/
The file type should start with ‘image/’ all image files are given the file type value ‘image/extension’ (where extension is any of jpg, jpeg, gif, etc. ). We allow a collection of file types: jpg or jpeg or gif or png or bmp – the file may contain any of these. They’re seperated by a | to indicate the file type may be ANY of these ( one ). You could as well just allow ALL image extensions. The pattern would then look like this:
/^image\/(.*)$/
As all images get the file extension starting with ‘image/’
We put it inside a regular if loop and use the preg_match function to check whether the pattern matched with the upload file extension.
Notice the file extension is set in $_FILES['uploadfile']['type'] and that we use the function strtolower so that for example
JPEG would become jpeg. So it won’t make any difference for capital letters – match the pattern as well as they’re converted to non-capital (lower) letters ).
$pattern_filetypes = "/^image\/(jpg|jpeg|gif|png|bmp)$/";
if(preg_match($pattern_filetypes, strtolower($_FILES['uploadfile']['type']))) {
//matched the pattern -> file type is allowed
}else{
//didn't match the pattern -> file type is not allowed
}
Put the pattern for the filetypes that are allowed inside a variable to make it easier readable and editable.
So, where do we put this inside our total script? It should be in the first loop atleast, as that’s where all the file handling takes place ( when the form was submitted ). The second loop inside that one, of our whole script checks, checks if there are any errors. It should be in the else part of that loop as that else part is executed when no errors were found. And then it will need to check the file type, and if that’s correct as well, it will execute the file uploading stuff:
File: upload.php
<?php if(!empty($_POST)) { if($_FILES['uploadfile']['error'] > 0) { echo "Error occured!"; }else{ //... no error occured - upload the file! ... //>>>>HERE<<<<< $pattern_filetypes = "/^image\/(jpg|jpeg|gif|png|bmp)$/"; if(preg_match($pattern_filetypes, strtolower($_FILES['uploadfile']['type']))) { //matched the pattern -> file type is allowed //Put the file handling script here (moved from below) $path = "uploads/".$_FILES['uploadfile']['name']; if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path)) { //... file successfully uploaded and moved to the path set in $path echo "File <b> ".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$path; }else{ //... could not move uploaded file to path set in $path echo "Error - could not move uploaded file to {$path}!"; } }else{ //didn't match the pattern -> file type is not allowed echo "Error - file type not allowed!"; } } } ?>
Retrieve errors & Handling
Now that we’ve got our file upload system work, we do want to be able to tell the user WHAT error occured if any. As now it just showed an error message if any error occured. Let’s have a closer look on that part again, pick it out of our script for a sec:
if($_FILES['uploadfile']['error'] > 0) {
echo "Error occured!";
When $_FILES['uploadfile']['error'] contains a value greater than 0, an error has occured. But what error occured can be told by checking the value ( number ) of $_FILES['uploadfile']['error'] which contains the number of the error occured. Here’s a list of what error each number represents:
[TABLE=5]
As you can see all numbers greater than 0 indicate an error ( we checked it correctly in the if loop: $_FILES['uploadfile']['error'] > 0 ). Now we’re going to create a switch loop which checks WHICH of the errors occured. We’ll be using the data from the table above:
switch($_FILES['uploadfile']['error']) {
case 1:
echo "Max file size exceeded";
break;
case 2:
echo "Max file size exceeded";
break;
case 3:
echo "File was only partially uploaded";
break;
case 4:
echo "File was not uploaded";
break;
case 5:
echo "Missing temp directory";
break;
case 6:
echo "Could not write file to disk";
break;
case 7:
echo "Upload stopped by file extension";
break;
}
Think that’s quite straight forward. It checks which error number occured ( value of $_FILES['uploadfile']['error']) and for each number it shows the corresponding error message. Let’s put it all together!
File: upload.php
<?php if(!empty($_POST)) { if($_FILES['uploadfile']['error'] > 0) { echo "Error occured - "; //>>>HERE<<< //which error occured? switch($_FILES['uploadfile']['error']) { case 1: echo "Max file size exceeded"; break; case 2: echo "Max file size exceeded"; break; case 3: echo "File was only partially uploaded"; break; case 4: echo "File was not uploaded"; break; case 5: echo "Missing temp directory"; break; case 6: echo "Could not write file to disk"; break; case 7: echo "Upload stopped by file extension"; break; } }else{ //... no error occured - upload the file! ... $pattern_filetypes = "/^image\/(jpg|jpeg|gif|png|bmp)$/"; if(preg_match($pattern_filetypes, strtolower($_FILES['uploadfile']['type']))) { //matched the pattern -> file type is allowed //Put the file handling script here (moved from below) $path = "uploads/".$_FILES['uploadfile']['name']; if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path)) { //... file successfully uploaded and moved to the path set in $path echo "File <b> ".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$path; }else{ //... could not move uploaded file to path set in $path echo "Error - could not move uploaded file to {$path}!"; } }else{ //didn't match the pattern -> file type is not allowed echo "Error - file type not allowed!"; } } } ?>
File Exists Check
Now one last thing we might want to do is check whether the uploaded file doesn’t already exist. We can simply use the function file_exists to do this.
if(file_exists('file/path/')) {
// file exists
}else{
// file doesn't exist
}
So in our case the path would be $path ( remember?). As we earlier set $path equal to:
$path = "uploads/".$_FILES['uploadfile']['name'];
Which is the path for the file to be uploaded to. But we first want to check if the file already exists in there, so we use the file_exists function.
if(file_exists($path)) {
// file exists
echo "File already exists!";
}else{
// file doesn't exist - continue uploading
}
We put it in the script right after the part where the $path is set ( which is in the loop where it starts uploading the file ):
File: upload.php
<?php if(!empty($_POST)) { if($_FILES['uploadfile']['error'] > 0) { echo "Error occured - "; switch($_FILES['uploadfile']['error']) { case 1: echo "Max file size exceeded"; break; case 2: echo "Max file size exceeded"; break; case 3: echo "File was only partially uploaded"; break; case 4: echo "File was not uploaded"; break; case 5: echo "Missing temp directory"; break; case 6: echo "Could not write file to disk"; break; case 7: echo "Upload stopped by file extension"; break; } }else{ //... no error occured - upload the file! ... $pattern_filetypes = "/^image\/(jpg|jpeg|gif|png|bmp)$/"; if(preg_match($pattern_filetypes, strtolower($_FILES['uploadfile']['type']))) { //matched the pattern -> file type is allowed //Put the file handling script here (moved from below) $path = "uploads/".$_FILES['uploadfile']['name']; //>>>HERE<<< if(file_exists($path)) { //file exists echo "File already exists!"; }else{ //file doesn't exist - continue uploading if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $path)) { //... file successfully uploaded and moved to the path set in $path echo "File <b> ".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$path; }else{ //... could not move uploaded file to path set in $path echo "Error - could not move uploaded file to {$path}!"; } } }else{ //didn't match the pattern -> file type is not allowed echo "Error - file type not allowed!"; } } } ?>
Done!
And that’s our final script! Hope you learnt something and have fun uploading
.
Modification Suggestions
<b>Change the path to url</b>
As with this file uploading system we let it show the relative PATH to the file, we could also make it show the url to the file uploaded. To do this you need to change this part of the script:
//... file successfully uploaded and moved to the path set in $path
echo "File <b>".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$path;
That’s where it shows the file being successfully uploaded -message. You see it shows the path which is set in $path. To make it show the URL, just create another variable for example like this:
$website_url = "http://mywebsite.com/directory_of_this_file"; /* url to the directory of this file (not the file itself) - for example: http://mywebsite.com/ or http://www.mywebsite.com/upload/ ) */
$file_url = $website_url."/".$path;
We created the variable $file_url which holds the url to your site / the path to the upload file which is the total url to the uploaded file.
//... file successfully uploaded and moved to the path set in $path
$website_url = "http://mywebsite.com/directory_of_this_file";
$file_url = $website_url."/".$path;
echo "File <b>".$_FILES['uploadfile']['name']."</b> successfully uploaded to ".$file_url."";
Cheers,
Admin.


Sat, Feb 6, 2010
PHP & MySql