Multiple File Upload Input

By  on  

Multiple File Upload

More often than not, I find myself wanting to upload more than one file at a time.  Having to use multiple "file" INPUT elements is annoying, slow, and inefficient.  And if I hate them, I can't imagine how annoyed my users would be.  Luckily Safari, Chrome, and Firefox have implemented a method by which users can upload multiple files within one INPUT element.

The HTML

<!-- IMPORTANT:  FORM's enctype must be "multipart/form-data" -->
<form method="post" action="upload-page.php" enctype="multipart/form-data">
  <input name="filesToUpload[]" id="filesToUpload" type="file" multiple="" />
</form>

Simply adding the multiple attribute allows for multiple files to be uploaded via one INPUT element.  If you're a stickler for validation, you'll want to assign the multiple attribute a value of multiple.

Listing Multiple Files with JavaScript

//get the input and UL list
var input = document.getElementById('filesToUpload');
var list = document.getElementById('fileList');

//empty list for now...
while (list.hasChildNodes()) {
	list.removeChild(ul.firstChild);
}

//for every file...
for (var x = 0; x < input.files.length; x++) {
	//add to list
	var li = document.createElement('li');
	li.innerHTML = 'File ' + (x + 1) + ':  ' + input.files[x].name;
	list.append(li);
}

The input.files property provides an array of files for which you can check the length;  if there's a length, you can loop through each file and access the file paths and names.

Receiving and Handling Files with PHP

if(count($_FILES['uploads']['filesToUpload'])) {
	foreach ($_FILES['uploads']['filesToUpload'] as $file) {
	    
		//do your upload stuff here
		echo $file;
		
	}
}

PHP creates an array of the files uploaded with the given INPUT's name.  This variable will always be an array within PHP.

Of course, you could a Flash-based equivalent for Internet Explorer and Opera, but having to add and support another component can be taxing.  Hopefully these browsers add support for multiple file uploads soon!

Recent Features

  • By
    CSS vs. JS Animation: Which is Faster?

    How is it possible that JavaScript-based animation has secretly always been as fast — or faster — than CSS transitions? And, how is it possible that Adobe and Google consistently release media-rich mobile sites that rival the performance of native apps? This article serves as a point-by-point...

  • By
    I&#8217;m an Impostor

    This is the hardest thing I've ever had to write, much less admit to myself.  I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life.  All of those feelings were very...

Incredible Demos

  • By
    Implement jQuery&#8217;s hover() Method in MooTools

    jQuery offers a quick event shortcut method called hover that accepts two functions that represent mouseover and mouseout actions. Here's how to implement that for MooTools Elements. The MooTools JavaScript We implement hover() which accepts to functions; one will be called on mouseenter and the other...

  • By
    Fancy FAQs with jQuery Sliders

    Frequently asked questions can be super boring, right? They don't have to be! I've already shown you how to create fancy FAQs with MooTools -- here's how to create the same effect using jQuery. The HTML Simply a series of H3s and DIVs wrapper...

Discussion

  1. Great thanks! I am always running into this problem project after project. I have been using http://www.uploadify.com/demo/ for IE users (flash alternative), it’s very easy to implement and customise (event handlers etc).

    • charisma

      hi alex crooks…but at the time you try to use session variable at your uploadify.php it’s can not …and finally i lucky to found this david walsh script becouse i like to build my own version multiple upload to my needed..shit i even try to create it’s should have uploadify interface i mean have file list after input type file change..hmm now i can continue again..thanks too david..

    • charisma

      hi alex crooks…but at the time you try to use session variable at your uploadify.php it’s can not becouse at the time someone else know what file be your form action..and i think their can direct use that file from their own computer to upload somegood file ^,^oO(%$&!)…and finally i lucky to found this david walsh script becouse i like to build my own version multiple upload to my needed..shit i even try to create it’s should have uploadify interface i mean have file list after input type file change..hmm now i can continue again..thanks too david..

  2. This is the only reason I ever use flash on a page. The lack of progress sadly still means it is needed, but I don’t see that being fixed anytime soon.

  3. Awesome! Thanks for sharing this little gem! It would make a welcome addition to certain modules in our in-house CMS.

  4. didn’t work in last opera

  5. Andy

    Doesn’t work in IE(8) or Opera. It would be helpful if you would add what browsers your tips work in, some Googler might find this page and later down the troubleshooting line get confused when it doesn’t work in a different browser.

  6. fuck, nice! i dont know about this, because I use opera always! ;)

  7. @Andy: Did you read the post? “Luckily Safari, Chrome, and Firefox have implemented a method by which users can upload multiple files within one INPUT element.”

    Please read the post next time.

    • Jack

      Hey. I’m not having any luck using this code. I’m constantly getting the ‘uploads’ index php error mentioned earlier in the comments. I tried looking at the source code of the example, but it’s different than what you posted here. It doesn’t call for a php script, the javascript is longer, there is an input, but no form and no submit button. Could you post a working example in a zipped archive?

    • I would try the same, like Andy, but you broke all my hope , despite I have read this part :)

  8. Dmitry

    Thanks David.

    This problem with upload arises from project to project. In my last project I tried http://www.aurigma.com/Products/ImageUploaderFlash/, it worked good enough with all browsers.

  9. The usual comments from people who don’t read a post (i.e. Dr Death and Andy).

    Not only do you say “Luckily Safari, Chrome, and Firefox have implemented a method by which users can upload multiple files within one INPUT element” but at the end you also say “Of course, you could a Flash-based equivalent for Internet Explorer and Opera, but having to add and support another component can be taxing. Hopefully these browsers add support for multiple file uploads soon!”

    I’m not sure how this at all confusing about the current state of browser support…

  10. The usual comments from people who don’t know how to read a post (i.e. Dr Death and Andy).

    Not only do you (David) say “Luckily Safari, Chrome, and Firefox have implemented a method by which users can upload multiple files within one INPUT element” but at the end you also say “Of course, you could a Flash-based equivalent for Internet Explorer and Opera, but having to add and support another component can be taxing. Hopefully these browsers add support for multiple file uploads soon!”

    I’m not sure how this at all confusing about the current state of browser support…

  11. Hey David, can you delete this one, and my first (or second) comment.., Something went wrong when posting (took ages) and I posted the comment again and they both ended up on this page. Thanks!

  12. kburn

    AWSUM!!

    It would be nice to find out a way to implement an uploading bar, to show the progress. ;)

  13. Chris Brewer

    Way cool. Thanks David. Would be super excellent to combine this capability with the capabilities of this script (http://the-stickman.com/files/mootools/multiupload/) in terms of removing the files from the queue of files to upload…

  14. This multiple upload thing should be a must-have-feature in modern browsers!

  15. JamesH

    Pretty cool, I wonder how long until ‘The Other’ browser implements something like this. Being limited to a single file per INPUT is a pain in the arse, and while the Flash alternatives solve the problem, I do not like having to use Flash to resolve a problem that shouldn’t of existed in the first place..but oh well, it’s the standard.

    Thanks for the heads up David!

  16. Thanks David,
    I’m going to add this feature to our web-apps it’s great. Next one is web-browser based drop-box’s straight from the desktop.

  17. Great article!

    Just wanted to mention: if you’re working with an XHTML doctype, then you’ll need to use multiple=”multiple”. Otherwise, multiple by itself will work. Same rule applies to all boolean attributes.

  18. Hi nice article.

    Thanks
    Addy

  19. cannot believe this is possible I tried everything, especiallly the Flash is awfull with loosing its session in everything but IE.
    Thank you for sharing, If it works , I will take you out in Amsterdam till you drop, I mean it !

  20. ncc50446

    If you are an Opera user, you can use this

    Opera has had it since Opera 6
    Just need to check their user agent and display the right one. A pain, but still doable.

  21. ncc50446

    Ok…Lets try that again lol
    Just put in the opening and closing html tags

    input type=”file” name=”filesToUpload[]” id=”filesToUpload[]” min=”1″ max=”9999″ /

  22. aldian

    Google docs has added new upload feature. It uses multiple file input and also works in IE eventhough have disabled flash. How did they manage it to work in IE?

  23. Marcelo Barros

    Please David, Can you share the complete code of this example? :D

    Thanks

  24. In $_FILES[‘uploads’][‘filesToUpload’] what is ‘uploads’? I don’t see it anywhere in your HTML and from what I can tell, it should just be the input element’s name, yet you have a multi-indexed format. Am I missing something? Thanks!

  25. Chris Brewer

    @pbink, $_FILES is the superglobal constant PHP uses to store items uploaded to the current script via POST.

    http://php.net/manual/en/reserved.variables.files.php

    • Mike

      pbink is asking about the [‘uploads’]… I’m having the same problem and am getting an error on my php page:

      Notice: Undefined index: uploads in C:\…….

      Thanks for any help you can give.

    • mtug

      Mike — have you received any assistance on this issue? I’m having the same issue although I don’t get the undefined index msg but am getting a count=0 in the file count parameter within php.

  26. Desidido

    Sir where can I download this all?? can i have the complete PHP and html script??? please..i want it..and can you do a combination of php and sql in multiple upload?? thanks! more power>..

  27. nefertiti

    Thanks for this! It was great and solved my problem, as I hate to have many input fields and click like crazy for many files! Thanks again!

  28. Gabriel

    Code for upload once (IE) or multiple (Fx, Chrome, Safari) in PHP

    for ($i=0; $i<count($_FILES['f_img']['name']); $i++){
    $ar = array();
    foreach (array_keys($_FILES['f_img']) as $arr){
    $ar[$arr] = $_FILES['f_img'][$arr][$i];
    }
    imager($ar);
    }

  29. mtug

    Some of the code didn’t make it to the post. The beginning looks like this:

    0)
    {
    echo “Error: ” . $_FILES[“uploads”][“error”] . “”;

  30. mtug

    well, the beginning still didn’t show up so you’ll have to trust I didn’t misscode it.

  31. Has anyone found code that will correctly detect the browsers that support this feature?

    You’ll have to exclude older versions of Firefox and safari, but I’m not clear on exactly which versions to detect, and I’m not keen on testing tons of different versions to figure this out.

  32. Tor

    So, I have a problem. Whenever I try to upload a bunch of pictures, only the first two gets uploaded.

    Can anyone tell me why that might be? The images are only like 60 KB each, and there’s less than 15 of them. I would be extremely pleased if anyone had the slightest idea about what my problem might be.

  33. Παύλος

    Ur the best! Helped a LOT!

  34. Regarding $_FILES[‘uploads’]

    The author, perhaps, missed out on the fact that PHP does quite a different structure for $_FILES when the above method is used.

    To access the data from these multiple files, you should do this:

    $_FILES[‘input_name_in_form’][‘name’][0] – gets you the original file name of the first image in the list while $_FILES[‘input_name_in_form’][‘name’][1] – gets you the name of the second file
    etc.
    you can see the whole contents of the $_FILES using print_r($_FILES)

    I think what I will do is write a custom function which just processes the $_FILES and returns an array of easily processable files.

  35. me

    Hello
    Thank you very much for this good code

  36. Lovepreet Singh

    your multiple file uploading function failed in internet explorer…

  37. thanks! this is what i need, it’s a key. not a complete code doing stuff. thanks again! :)

  38. Nice work mate! That’s makes me one step closer to the edge. Looking for this for a long time. Hope idiot ie will support multiple somehow.

  39. skor

    thanks for the code..

    but how do I save the images that I selected to my admin folder?

    i have this code for single upload:

    but i dont know what to do in multiple…
    sorry I’m newbie :)

  40. skor
  41. edoardo849

    Dude, 6 hours… I googled 6 hours on this issue until I found out your post. Only one word: thanks!!!

  42. Hi,

    After a long search I have also created a multiple file uploader using ajax with a jquery progressbar. It is a combination of two famous packages. May somebody will get help of it

    http://myphplibrary.blogspot.in/2012/03/jquery-file-uploader-with-progress-bar.html

  43. kright

    Thank you for tutorial, it’s really great, I have a trouble when I try your demo I can upload over 200 files tandsis I try locally by following the tutorial on your explanation, I do that has 19 upload files even if I select the files delas of 19, he has only 19 upload files. I would like to know how to do so I can upload more than 19 files, also it is possible to have the source of your demo.

  44. kright

    I achieved some of what I wanted, we had to increase the number of file upload in php.ini, for variable max_file_uploads because the default is 20. For those who do not have this variable in php.ini, you just add it.

  45. Thanks for sharing, It helped me a lot….

  46. Really an interesting article! I always thought that to upload two or more files, I should call a flash or java code! Do you know if the new version of IE have the same problem and need the flash plug in to upload more than one files?
    I think it would fantastic if all browser can use this method and leave flash one time forever for this things :)
    Anticipated thank for the answer!! ;)

    Reguard,
    Andrew

  47. Ben Gilbert

    This is Probably a bit late, but here is the PHP portion for the handling of the files in the array that will work…

    if(count($_FILES['filesToUpload']['name'])) {
    $i = 0;
      foreach ($_FILES['filesToUpload']['name'] as $file) {
        $img = "uploads/clients/".$file;
        move_uploaded_file($_FILES['filesToUpload']['tmp_name'][$i], $img);
        chmod( $img , 0777 );
        
     	$company = $_POST['exsistingcompanies'];
    
        $time = strtotime($row[time] . ' + 3 hours'); 
        $time = date("m/d/y - h:i a", $time);
    
        $query = "INSERT INTO media_files SET client_id='$company', name='$img', date_uploaded='$time'";
    	queryMysql($query);
        $i++;
        }
      }
    
    • Azhelle

      Hi Ben,

      been looking for this piece of code for hours. I really appreciate it.

      To David,

      I also appreciate your post.

      Both of you have been a great help. THANKS A LOT! :)

  48. Here is a PHP Upload code (that actually works):

    I used “file” instead of “filesToUpload” for the form field:

    Thanks for the great article!

    Pete

    • Sorry it stripped out all my PHP code:

      session_start();
      
      if (isset($_POST["submit"]))
      {
      	if(count($_FILES['file']['name'])) 
      	{        
              $target="uploads/";               
              $count=0;
              
              foreach ($_FILES['file']['name'] as $filename) 
              {
                  $temp=$target;
                  $tmp=$_FILES['file']['tmp_name'][$count];
                  $count=$count + 1;
                  $temp=$temp.basename($filename);
                  move_uploaded_file($tmp,$temp);
                  $temp='';
                  $tmp='';
              }
      	}
      }
      
  49. Farhan

    Hey can any one tell me how to add random file name generating command in this code,thanks…

    • Farhan

      $uploaddir = “profilepictures”;
      if(is_uploaded_file($_FILES[‘file’][‘tmp_name’]))

      {
      move_uploaded_file($_FILES[‘file’][‘tmp_name’],$uploaddir.’/’.$_FILES[‘file’][‘name’]);
      print “Your picture has been uploaded successfully!”;
      }

  50. guganraj.p

    any one help me how to select multiple file using java script.i have the code but that not work in ie only chrom and firefox,help me how to in ie..

  51. chaman
    var list = document.getElementById('fileList')
    

    Where is fileList Element in HTML

    • JW

      The list is actually the that open for listing all the file name. I know this when I open inspect in demo site.

  52. Josh
    <p>
        <strong>Upload Files:</strong>
    	<input type="file" name="filesToUpload" id="filesToUpload" multiple="" onChange="makeFileList();" />
    </p>
    <p>
    	<strong>Files You Selected:</strong>
    </p>
    <ul id="fileList"><li>No Files Selected</li></ul>
    
    <script type="text/javascript">
    	function makeFileList() {
    		var input = document.getElementById("filesToUpload");
    		var ul = document.getElementById("fileList");
    		while (ul.hasChildNodes()) {
    			ul.removeChild(ul.firstChild);
    		}
    		for (var i = 0; i < input.files.length; i++) {
    			var li = document.createElement("li");
    			li.innerHTML = input.files[i].name;
    			ul.appendChild(li);
    		}
    		if(!ul.hasChildNodes()) {
    			var li = document.createElement("li");
    			li.innerHTML = 'No Files Selected';
    			ul.appendChild(li);
    		}
    	}
    </script>
    
    • JW

      omg thanks so much! I have been searching for so long why my file name list not showing up, this save my life !

  53. Does “multiple” work on mobile devices?

  54. I was wondering if there is a way to remove a already selected file?

  55. Pat Mächler

    I came by while looking for a good solution.
    In the end I have decided for Dropzone.js which is published with a permissive MIT license, very easy to use & also offers Drag&Drop functionality
    http://www.dropzonejs.com/

  56. With a little correction to the code, like removing the error index from $_FILES["images"]["error"] and replacing it with $_FILES["images"]["name"], it works.

  57. Hello everyone, the article didn’t state that the JavaScript part should be in a function that should be executed with the onChange event of the file input field. I had to find that out by viewing the source of the demo. Please update.

    Also, it should help to replace the portion of the JavaScript that’s,

    //empty list for now...
    while (list.hasChildNodes()) {
    	list.removeChild(ul.firstChild);
    }
    

    and change it to:

    //empty list for now...
    while (list.hasChildNodes()) {
    	list.removeChild(document.getElementById('fileList').firstChild);
    }
    

    I had a problem while testing in FireFox 50 and this was what finally fixed it. the error message was, unidentified element, ul.

    The original code makes perfect sense but it didn’t work on my Firefox 50 till I changed it to the correction above.

  58. mike

    Nice tutorial :)
    Exactly what i was looking for…With a slight addition. You see i want to enable user to upload images+a caption for each. So next to the filename i want a text input, what puzzles me is how to get in the php form submission part the connection that the x caption is for the x image, any ideas?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!