20. June 2013 7 min read

Upload multiple files using html5 and php

I have recently got into more user friendly admin interfaces and one of the obstacles I stumbled upon was uploading multiple images or uploading multiple files using a simple form on admin page. There are much more suitable options to transfer files on server (ftp), but the problem is that most people do not even know what ftp is and they just want Facebook alike interface to upload their photos to website. Every decent CMS (Content manager system) has this functionality, but my main idea was to develop my own, which will do some other things (more in other related posts). By default I am against CMS, because you never know what is inside and you never know where some so called feature will bite you in rear.
Using a simple html5 form you can now select multiple files into your form input.As a reminder - do not make this upload public as people can upload anything they wish to your server (well you can pick it out on receiving side).
html5 code would look like this:

<!-- please note that form enctype must be must be "multipart/form-data" -->
<form method="post" action="wheretosend.php" enctype="multipart/form-data" 

<input name="filesToUpload[]" id="filesToUpload" type="file" multiple="multiple"> 
<input type="submit" value="Send Files">

This was the multiple files sending part (nicely implemented with html5), but we still need the receiving server part of the code to save this photos/files somewhere. There is not much to say at this point, except that you will receive a POST array of files and you need to surf through it by doing your thing. So receiving server php file should have something like this:

if(count($_FILES['filesToUpload']['name'])) {
    for($i=0; isset($_FILES['filesToUpload']['name'][$i]);$i++) {
        $filename=str_replace(" ","_",$_FILES['filesToUpload']['name'][$i]);
        //attention on permissions for your uploaddir - you need to get them to 
        //right (server user) owner with: chown user:group
        $move_file = move_uploaded_file($_FILES['filesToUpload']['tmp_name'][$i],
        //we have moved our file from tmp folder of our server OS into directory 
        //we control. Do not forget that you can upload any file so if someone 
        //uploads a script and you are sharing the folder where you moved your
        //file with rest of the world, it will give hacker a  window to enter
        //your server
else echo 'Something went wrong as number of files received is: 
' . count($_FILES['filesToUpload']['name']);

Now lets see what additional problems could be. We all know http protocol is not exactly best to transfer large files, so there are some internal server limitation on amount of data it can receive using POST (same as limitations on length of URL). This might give you additional headaches, but I have discovered some nice settings which you need to adjust to receive bigger files. To find where you have your php.ini configuration file simply run:

php -i | grep php.ini

This will return your configuration file path and load it. Now if you are using php5 you want to upgrade to newest possible version and dump that good old Suhosin (an extension which protects your php code from security breaches). Suhosin is no longer maintained and php is now fixed of all that leaks (and has some new), so that php 5.4 version protects you good enough without it. In php.ini you need to change/adjust to your needs (bigger the files bigger the numbers mostly):

; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 3600

; Maximum amount of time each script may spend parsing request data. Its a good
; idea to limit this time on productions servers in order to eliminate unexpectedly
; long running scripts.
; Note: This directive is hardcoded to -1 for the CLI SAPI
; Default Value: -1 (Unlimited)
; Development Value: 60 (60 seconds)
; Production Value: 60 (60 seconds)
; http://php.net/max-input-time
max_input_time = 3600

; How many GET/POST/COOKIE input variables may be accepted
; max_input_vars = 1000

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 1024M

; Maximum size of POST data that PHP will accept.
; http://php.net/post-max-size
post_max_size = 2G

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 6000M

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 600

I think comments explain you everything but just be aware that you need to reload php.ini (with command above) to get things changed. Useful trick is also to create blank php to check variables on your site (does not need to be blank, just dont use it in production):

//this lists you all variables from php.ini that are used for your php

This covers multiple file uploads and whatever issues you might have with php and html regarding this except for one: your webserver might also have some limits. I use nginx and I have just added:

server {
    client_max_body_size 10000M;

I hope you now dont have any more problems uploading multiple large files to your php server. Once again I would underline that sharing directory you are saving your files is not safe at all. You either control your input or your output.

Newest from this category: