A Simple File Upload Script using PHP

54

Hi peeps,

Ever found yourself wondering how to create a File Upload System using PHP? Today is your lucky day! :P Follow me and I’ll show you how to implement a simple file upload script in your site using PHP.

What we need to get started:

  • A Web Server (like XAMPP) or Internet Host with Php capabilities.
  • Basic to semi-advanced Php knowledge.
  • Basic knowledge of HTML.
  • A text editor to create our little script (like notepad).
  • A folder in our server where to upload the files (eg. uploads, chmodded 777)

The Form

The first thing we need is the form that will allow our visitors to select an upload their file to our site. Here’s a sample snippet (which you can also download for testing purposes :D ):

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html charset=iso-8859-2" />
<title>Rauru.com - Upload Test</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    <label>File:</label> <input type="file" name="file" /><br />
    <input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

Let’s take a closer, deeper look to this form. As you can see, it’s just like any form you might have previously seen in other places except that this time we’re adding a special attribute: ENCTYPE. With it, we are telling our visitor’s browser that this form handles files by setting multipart/form-data as it’s value.

Once the user clicks on the Submit button, the form will send all the data via POST to our script, upload.php, which will handle it and save it to our uploads folder (you didn’t forget to create it, did you?)

The Upload Script

Before we get started, there are a few things that we need to know in order to understand what this snippet do. Php has some predefined variables called Super Variables. These include $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_ENV, $_FILES and $_REQUEST.

$_FILES is an array that will contain all the information of our uploaded file. The contens of $_FILES are saved as follows:

  • $_FILES['file']['name']: the original name of the file in the visitor’s computer.
  • $_FILES['file']['type']: the mime-type of our file (that is, the file type).
  • $_FILES['file']['size']: the size of the uploaded file (in bytes).
  • $_FILES['file']['temp_name']: The temporary filename of the file in which the uploaded file was stored on the server.
  • $_FILES['file']['error']: The error code associated with this upload.

Note that ‘file‘ is the name we set for our file input field in our upload form. It can be whatever you want! Here’s our script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
// Upload directory: remember to give it write permission!
$uploaddir = "upload/";
// what file types do you want to disallow?
$blacklist = array(".php", ".phtml", ".php3", ".php4", ".php5", ".exe", ".js",".html", ".htm", ".inc");
 // allowed filetypes       
$allowed_filetypes = array('.jpg','.gif','.bmp','.png');
 
if (!is_dir($uploaddir)) {
    die ("Upload directory does not exists.");
}
if (!is_writable($uploaddir)) {
    die ("Upload directory is not writable.");
}
 
if ($_POST['submit']) {
 
    if (isset($_FILES['file'])) {
        if ($_FILES['file']['error'] != 0) {
            switch ($_FILES['file']['error']) {
                case 1:
                    print 'The file is too big.'; // php installation max file size error
                    exit;
                    break;
                case 2:
                    print 'The file is too big.'; // form max file size error - DEPRECATED
                    exit;
                    break;
                case 3:
                    print 'Only part of the file was uploaded.';
                    exit;
                    break;
                case 4:
                    print 'No file was uploaded.';
                    exit;
                    break;
                case 6:
                    print "Missing a temporary folder.";
                    exit;
                    break;
                case 7:
                    print "Failed to write file to disk";
                    exit;
                    break;
                case 8:
                    print "File upload stopped by extension";
                    exit;
                    break;
            }
        } else {
            foreach ($blacklist as $item) {
                if (preg_match("/$item$/i", $_FILES['file']['name'])) {
                    echo "Invalid filetype !";
                    unset($_FILES['file']['tmp_name']);
                    exit;
                }
            }
            // Get the extension from the filename.
            $ext = substr($_FILES['file']['name'], strpos($_FILES['file']['name'],'.'), strlen($_FILES['file']['name'])-1);
			// Check if the filetype is allowed, if not DIE and inform the user.
			if(!in_array($ext,$allowed_filetypes)){
				die('The file you attempted to upload is not allowed.');
			}
			if (!file_exists($uploaddir . $_FILES["file"]["name"])) {
				// Proceed with file upload
				if (is_uploaded_file($_FILES['file']['tmp_name'])) {
					//File was uploaded to the temp dir, continue upload process
					if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $_FILES['file']['name'])) {
						// uploaded file was moved and renamed succesfuly. Display a message.
						echo "Upload successful!";
					} else {
						echo "Error while uploading the file, Please contact the webmaster.";
						unset($_FILES['file']['tmp_name']);
					}
				} else {
					//File was NOT uploaded to the temp dir
					switch ($_FILES['file']['error']) {
						case 1:
							print 'The file is too big.'; // php installation max file size error
							break;
						case 2:
							print 'The file is too big.'; // form max file size error
							break;
						case 3:
							print 'Only part of the file was uploaded';
							break;
						case 4:
							print 'No file was uploaded';
							break;
						case 6:
							print "Missing a temporary folder.";
							break;
						case 7:
							print "Failed to write file to disk";
							break;
						case 8:
							print "File upload stopped by extension";
							break;			
					}			
				}
			} else { // There's a file with the same name
				echo "Filename already exists, Please rename the file and retry.";
				unset($_FILES['file']['tmp_name']);
			}
        }
    } else { // user did not select a file to upload
        echo "Please select a file to upload.";       
    }
} else { // upload button was not pressed
    header("Location: form.html");
}
?>

Now, what does our little script do?:

  1. Set our upload folder.
  2. Set a fyletype blacklist and a filetype whitelist.
  3. Check that our uploads directory exists and is writable.
  4. Now, we validate that our user clicked on the Submit button. If he didn’t then redirect him to the form.
  5. Check if our super variable $_FILES has found any error on our uploaded file.
  6. Validate our uploaded file against our file type blacklist to prevent people uploading things that we don’t want on our server.
  7. Check that the file doesn’t exist. If there’s another file with the same name we alert our visitor and abort the upload process. Otherwise we save the file in our uploads folder and let him know that the upload was succesful.

Hope that helps ;)

P. S.: oh, and if you liked my tutorial please don’t forget to Digg it! :D

Did you enjoy reading this article? Share it!

  • Fave this blog on Technorati!
  • Digg this!
  • Share this post on Reddit!
  • Share this post on Delicious!
  • Stumble this!

54 Responses to "A Simple File Upload Script using PHP"

  1. Wakish May, 09 2008

    It’s a nice one, definelty handy specially for php newbies..
    Keep going!
    - Wakish -

    Reply to this comment

  2. rain May, 09 2008

    i dont have a website yet.. but its someone who told me to upload something to his website.. so i found dis tutorial is didactic.. good for newbies
     

    Reply to this comment

  3. jose May, 09 2008

    Excelente! muchas gracias! :D

    Reply to this comment

  4. Ikki May, 09 2008

    @jose: De nada ;)

    Reply to this comment

  5. Karen May, 09 2008

     Do just need to upload the uploads folder, form.php and upload.php on to my site? Because in my browser when i click submit it has just a blank page… What did i do wrong?

    Reply to this comment

  6. Ikki May, 09 2008

    @Karen: You need to create a “upload” folder on your server and give it writing permissions before using this script. Remember to change the path to its location in line 3!

    Give it a try and let me know if it worked, ok? ;)

    Reply to this comment

  7. Karen May, 09 2008

    Gave ‘upload’ folder writing permissions 0774.  Changed the path to ‘public_html/orielchambers/upload’ (the path on my server). The browser sends my page to upload.php with blank page still.

    Reply to this comment

  8. Ikki May, 09 2008

    @Karen: I think you’re setting the wrong path. Try this: put both scripts (the form and the uploaded script) in the folder “orielchambers” and set your $uploaddir variable to “upload/”.

    If it doesn’t work please let me know. I may give you a hand with your script if you allow me to do so.

    Reply to this comment

  9. Karen May, 09 2008

    No sorry it doesnt work.
    Here’s my script:-

    <?php
    // Upload directory: remember to give it write permission!
    $uploaddir = “upload/”;
    // what file types do you want to disallow?
    $blacklist = array(“.php”, “.phtml”, “.php3?, “.php4?, “.php5?, “.exe”, “.js”,“.html”, “.htm”, “.inc”);
     // allowed filetypes       
    $allowed_filetypes = array(‘.jpg’,‘.gif’,‘.bmp’,‘.png’);
     
    if (!is_dir($uploaddir)) {
        die (“Upload directory does not exists.”);
    }
    if (!is_writable($uploaddir)) {
        die (“Upload directory is not writable.”);
    }
     
    if ($_POST['submit']) {
     
        if (isset($_FILES['file'])) {
            if ($_FILES['file']['error'] != 0) {
                switch ($_FILES['file']['error']) {
                    case 1:
                        print ‘The file is too big.’; // php installation max file size error
                        exit;
                        break;
                    case 2:
                        print ‘The file is too big.’; // form max file size error - DEPRECATED
                        exit;
                        break;
                    case 3:
                        print ‘Only part of the file was uploaded’.;
                        exit;
                        break;
                    case 4:
                        print ‘No file was uploaded.’;
                        exit;
                        break;
                    case 6:
                        print “Missing a temporary folder.”;
                        exit;
                        break;
                    case 7:
                        print “Failed to write file to disk”;
                        exit;
                        break;
                    case 8:
                        print “File upload stopped by extension”;
                        exit;
                        break;
                }
            } else {
                foreach ($blacklist as $item) {
                    if (preg_match(“/$item\$/i”, $_FILES['file']['name'])) {
                        echo “Invalid filetype !”;
                        unset($_FILES['file']['tmp_name']);
                        exit;
                    }
                }
                // Get the extension from the filename.
                $ext = substr($_FILES['file']['name'], strpos($_FILES['file']['name'],‘.’), strlen($_FILES['file']['name'])-1);
    // Check if the filetype is allowed, if not DIE and inform the user.
    if(!in_array($ext,$allowed_filetypes)){
    die(‘The file you attempted to upload is not allowed.’);
    }
    if (!file_exists($uploaddir . $_FILES["file"]["name"])) {
    // Proceed with file upload
    if (is_uploaded_file($_FILES['file']['tmp_name'])) {
    //File was uploaded to the temp dir, continue upload process
    if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $_FILES['file']['name'])) {
    // uploaded file was moved and renamed succesfuly. Display a message.
    echo “Upload successful!”;
    } else {
    echo “Error while uploading the file, Please contact the webmaster.”;
    unset($_FILES['file']['tmp_name']);
    }
    } else {
    //File was NOT uploaded to the temp dir
    switch ($_FILES['file']['error']) {
    case 1:
    print ‘The file is too big.’; // php installation max file size error
    break;
    case 2:
    print ‘The file is too big.’; // form max file size error
    break;
    case 3:
    print ‘Only part of the file was uploaded’;
    break;
    case 4:
    print ‘No file was uploaded’;
    break;
    case 6:
    print “Missing a temporary folder.”;
    break;
    case 7:
    print “Failed to write file to disk”;
    break;
    case 8:
    print “File upload stopped by extension”;
    break;
    }
    }
    } else { // There’s a file with the same name
    echo “Filename already exists, Please rename the file and retry.”;
    unset($_FILES['file']['tmp_name']);
    }
            }
        } else { // user did not select a file to upload
            echo “Please select a file to upload.”;
        }
    } else { // upload button was not pressed
        header(“Location: form.html”);
    }
    ?>

    Reply to this comment

  10. Karen May, 09 2008

    Upload.php and form.html and the ‘uploads’ folder are all in orielchambers folder on public.html.

    Reply to this comment

  11. Ikki May, 09 2008

    @Karen: I think I found your problem. See this line in your script:

    $blacklist = array(“.php”, “.phtml”, “.php3?, “.php4?, “.php5?, “.exe”, “.js”,“.html”, “.htm”, “.inc”);

    You’re missing some closing double-quotes in your blacklist array. It should be like this:

    $blacklist = array(“.php”, “.phtml”, “.php3?”, “.php4?”, “.php5?”, “.exe”, “.js”,“.html”, “.htm”, “.inc”);

    It should work now. You were getting a blank page because of a PHP error. You should enable PHP to display errors in your scripts in order to let you know when something goes wrong (but use it only on testing enviroments, never on production enviroments!).

    Let me know if it worked, ok?

    Reply to this comment

  12. Karen May, 09 2008

    Corrected the line, and….. it still gives me a blank page. This one is weird!

    Reply to this comment

  13. Ikki May, 09 2008

    @Karen: Strange. I didn’t find any further errors on your script. Try adding this line to your upload.php:

    error_reporting(E_ALL);

    This function will tell PHP to display any errors it might encounter while executing this script. Please copy the error message and post it here :)

    Reply to this comment

  14. Karen May, 09 2008

    Still a blank page. 

    Reply to this comment

  15. Ikki May, 09 2008

    @Karen: weird. I’m beginning to think that your problem is not your code but your host’s server configuration. Try adding these commands to your .htaccess file in public_html to override any settings from your host and force their server to display PHP errors:

    php_flag display_errors on
    php_flag display_startup_errors on
    php_value error_reporting 2047

    You might algo want to try this.

    If none of the above works you might want to contact your admin.

    Reply to this comment

  16. Karen May, 09 2008

    This brings up an error:-

    Parse error: syntax error, unexpected ‘,’ in /data01/hunter/public_html/orielchambers/upload.php on line 5

    (This is line 5):-

    $blacklist = array(“.php”, “.phtml”, “.php3?”, “.php4?”, “.php5?”, “.exe”, “.js”,“.html”, “.htm”, “.inc”);

    Reply to this comment

  17. Ikki May, 09 2008

    @Karen: haha xD Damn line! Ok my guess is that the formated double-quotes (“ ”) are the ones causing all this mess. Replace line 5 with:

    $blacklist = array(”.php”, “.phtml”, “.php3?”, “.php4?”, “.php5?”, “.exe”, “.js”, “.html”, “.htm”, “.inc”);

    Reply to this comment

  18. Seneca May, 09 2008

    Parse error: parse error, unexpected ‘;’ in /home/content/***/html/upload.php on line 24

    Edited by Ikki - Reason: sensitive info in the comment

    Reply to this comment

  19. Ikki May, 09 2008

    @Seneca: Hi there, mind to share your script with me? It’s hard to tell why are you getting this error without looking at the source code

    Reply to this comment

  20. Seneca May, 09 2008

    i’m basically trying to make a simple upload form for artists to upload their demo submissions directly to my folder: http://www.audiologicrecordings.com/contact.html

    Reply to this comment

  21. Ikki May, 09 2008

    @Seneca: Try putting your script into a .zip file, upload it to your host and send me the link so I can check it.

    Reply to this comment

  22. Seneca May, 09 2008
  23. Ikki May, 09 2008

    @Seneca: Found the error. Lose the dot (”.”) at the end of line 30, that was the thing causing the problem! :)

    Reply to this comment

  24. Jd May, 09 2008

    Can you implement a category selector for this? or make a tutorial on it so people can select which folder the files will be stored on? thanks :)

    Reply to this comment

  25. Ikki May, 09 2008

    @Jd: Hi there. I’m sure I can come up with something like that. I’ll give it a try as soon as I get some spare time ;) Thanks for the idea!

    Reply to this comment

  26. ziggurat May, 09 2008

    So how would you alter the code to allow multiple file uploads?

    Reply to this comment

  27. ziggurat May, 09 2008

    or not overwrite that last upload?

    Reply to this comment

  28. Ikki May, 09 2008

    @ziggurat: well, I’d do something like this. I haven’t tested it yet but it should work.

    Reply to this comment

  29. Eneza May, 09 2008

    The script should be tested first by the author itself? You are talking to one script right, or Karen has injected some codes of his own.

    Reply to this comment

  30. Eneza May, 09 2008

    It works very fine!!!!!! Good Job!

    Reply to this comment

  31. Ikki May, 09 2008

    @Eneza: Hi there. Yes, Karen did some customizations to the script to make it work for her site. I guess she either finally got it working -and forgot to let me know- or she found another script that worked for her.

    Anyways, I’m glad to know that you found here what you were looking for :)
    Cheers!

    Reply to this comment

  32. wow May, 09 2008

    Hey how can i make it where people can look through a list of files to download when they get uploaded?

    Reply to this comment

  33. Ikki May, 09 2008

    @wow: well, this script doesn’t do that. Some time ago, I found this script. I haven’t tested it but it should work fine.

    Hope that helps ;)

    Reply to this comment

  34. wow May, 09 2008

    @Ikki thank you

    Reply to this comment

  35. dabo911 May, 09 2008

    when it says”ouplad complete on the following page how can I show the image they’ve uploaded under it?

    Thanks!

    Reply to this comment

  36. Ikki May, 09 2008

    @dabo911: Try replacing line 71 with:
    echo “Upload successful!”;
    echo “< br / > < img src='" . $uploaddir . $_FILES['file']['name'] ."' / >“; // remove the whitespaces from the HTML tags!

    Reply to this comment

  37. MechanicsPal May, 09 2008

    I am quite curious as to why I am having an issue with the $uploaddir not being recognized when it is clearly present on the server via FTP & server host confirmation. I have tried numerous directories in order to test it out… and have tried a number of different CHMODs for the dirs and subdirs… It plays out something like this…: [modification] $uploaddir = “dir/acctnum/” and yet I think that PHP still hates me. Any ideas, commments, concerns? ((suggestions?? :P(((

    Basically…

    Ba

    Reply to this comment

  38. Ikki May, 09 2008

    Hey Pal,

    Is the script displaying any error at all? Also, Try chmodding ‘acctnum’ to 777.

    Reply to this comment

  39. ejsiddiqui May, 09 2008

    Great Script, but just a little problem.
    What if a file name has more than one dot “.”.
    e.g. 28.12.08.jpg  In this case the script will split the file name from first dot and ll give the name as 12.08.jpg and say that “The file you attempted to upload is not allowed.”.
    Here is the solution
    <code>
    function findexts ($filename)
    {
    $filename = strtolower($filename) ;
    $exts = split(”[/\\.]“, $filename) ;
    $n = count($exts)-1;
    $exts = $exts[$n];
    return “.”.$exts;
    }

    // Get the extension from the filename.
    $ext = findexts($_FILES['file']['name']);
    </code>
    Hope this would help.

    Reply to this comment

  40. MechanicsPal May, 09 2008

    @Ikki -

    I appreciate the fast response.  It was an error on my part.  I had created the site to pull specific data out of a folder a few directories away… and in doing so pretty much made it more difficult than it should be when it comes to uploads.  I did figure out what i had to do, and again, I appreciate the quick response.

    ~MechPal

    Reply to this comment

  41. Ikki May, 09 2008

    @MechanicsPal: Glad to know that you got it working, mate! Thanks for letting me know :)

    Reply to this comment

  42. ofi May, 09 2008

    hi
    great script, how can i get those uploaded files and print it out

    Reply to this comment

  43. Jim May, 09 2008

    You should also check the mime-type. :)

    Reply to this comment

  44. Sonic May, 09 2008

    This is the best tutorial on the subject I’ve found. It seems all the others expect one to have register_globals set to on. Also, you explained the code well, which a lot of others don’t do.
    Anyway, thanks for the great tutorial!

    Reply to this comment

  45. kyle May, 09 2008

    I get this error report:

    The server encountered an unexpected condition which prevented it from fulfilling the request.
    The script had an error or it did not produce any output. If there was an error, you should be able to see it in the error log.

    Ive change the folder permissions and everything, any ideas before i go mad??

    Reply to this comment

    • Ikki May, 09 2008

      Hi Kyle, Have you modified the script in any ways? Usually, you get a 500 server error because of a script failure, or corrupt output from it.

      Reply to this comment

  46. Luis May, 09 2008

    Hi Hector,
    I´ve been searching for a upload script, and yours looks great but it does not work, it just refreshes the page where the form is contained.
    I just modified the name of form.html to my own site.html where the form is contained. The script is as it is here.
    Im using dreamweaver CS4 and my web host allows almost everything.
    The upload folder is located where the script.php and the site.html are.
    Persmisisons are set to 0777
    I hope you can help me.
    Thanks

    Reply to this comment

    • Ikki May, 09 2008

      Hi Luis, are you getting any php errors?

      Reply to this comment

  47. valkya May, 09 2008

    i get an error saying only part of the file aws uploade…y is this so!

    Reply to this comment

    • Ikki May, 09 2008

      Hi valkya. Apparently, the file you were trying to upload exceedes the maximum file size specified at php.ini. Contact your host and ask them to increase its value to 10MB.

      Reply to this comment

  48. Macca May, 09 2008

    Ikki
    Your script is brilliant and it works extremely well.
    What I want to do is create a Resume/CV or a Certificate as a form with fields and background images.  Then I want to allow the user to fill in the form and then where th”image” place holders are, I want the user to upload their image (and there may be more than one on the form), then they hit submit to view/review what they have done and have the ability to edit before completion.
    When they are happy with what  they have they can save it for later retrieval as well as Print the resume/certificate to their printer.
    I am prepared to pay to have this done.
    Macca

    Reply to this comment

    • Ikki May, 09 2008

      I’m sorry mate, I’m not freelancing right now as I’m already working on a few projects that are keeping me busy. Contact me again in a couple of weeks if you haven’t found someone for the job.

      Reply to this comment

  49. Macca May, 09 2008

    Forgot to say that I use Joomla as my CMS. Integration would be great but if not I still need it..
    Regards
     
    Macca

    Reply to this comment

Leave a Reply

By commenting here, you agree to abide by the comment policy of this blog.