143

I want to upload multiple files and store them in a folder and get the path and store it in the database... Any good example you looked for doing multiple file upload...

Note: Files can be of any type...

udaya
  • 9,598
  • 15
  • 48
  • 67
  • 2
    Here is a good example for you to follow: [EXAMPLE](http://www.justin-cook.com/wp/2006/07/17/upload-multiple-files-at-once-with-php/) – Strong Like Bull Apr 24 '10 at 14:19
  • @sarfraz I had weekend ... Just now i tried the example it awsome so easy – udaya Apr 28 '10 at 05:36
  • @sarfraz I tried to generate the from an add click i got the 's on add click but the result is not achieved Can you see my new question posted – udaya Apr 28 '10 at 07:08

14 Answers14

321

Some further explanation might be useful for someone trying to upload multiple files. Here is what you need to do:

  • Input name must be be defined as an array i.e. name="inputName[]"
  • Input element must have multiple="multiple" or just multiple
  • In your PHP file use the syntax "$_FILES['inputName']['param'][index]"
  • Make sure to look for empty file names and paths, the array might contain empty strings. Use array_filter() before count.

Here is a down and dirty example (showing just relevant code)

HTML:

<input name="upload[]" type="file" multiple="multiple" />

PHP:

//$files = array_filter($_FILES['upload']['name']); //something like that to be used before processing files.

// Count # of uploaded files in array
$total = count($_FILES['upload']['name']);

// Loop through each file
for( $i=0 ; $i < $total ; $i++ ) {

  //Get the temp file path
  $tmpFilePath = $_FILES['upload']['tmp_name'][$i];

  //Make sure we have a file path
  if ($tmpFilePath != ""){
    //Setup our new file path
    $newFilePath = "./uploadFiles/" . $_FILES['upload']['name'][$i];

    //Upload the file into the temp dir
    if(move_uploaded_file($tmpFilePath, $newFilePath)) {

      //Handle other code here

    }
  }
}
starball
  • 20,030
  • 7
  • 43
  • 238
Andy Braham
  • 9,594
  • 4
  • 48
  • 56
  • 12
    @Sven Yes it is supported in HTML5 check out this [link](http://www.w3schools.com/html5/att_input_multiple.asp) , my bad looks like IE doesn't support this tho... Geeze our life would be so much easier if everyone just went by the standards... LOL – Andy Braham Nov 22 '12 at 17:09
  • Andy this is good work. The only downside to having a separate input for each file is with `multiple`, I lose the opportunity for users to enter a title and caption at the same time. Minor thing - I can upload then let them modify title/caption later. – a coder Jan 15 '13 at 19:29
  • One other thought would be to offer an option of upload from disk, or obtain from entered URL. – a coder Jan 15 '13 at 19:30
  • 8
    @AndyBraham The `multiple` attribute of the input element is boolean, meaning you don't supply it a value: `` See the HTML5 spec: http://www.w3.org/TR/2011/WD-html5-20110525/common-input-element-attributes.html#the-multiple-attribute – Rob Johansen Jun 21 '13 at 13:45
  • 12
    It's worth mentionning that the user has to select all files at once. Any further selection attempt will cancel previous selection. – Skippy le Grand Gourou Apr 06 '15 at 11:00
  • 4
    @AlienBishop is not quite correct here, multiple="multiple" is perfectly fine and is included in the specs as an alternative. – kojow7 Oct 09 '15 at 22:18
  • @kojow7: Would you care to provide a reference? What you describe is not in the editor's draft, which was updated just two days ago: http://www.w3.org/html/wg/drafts/html/master/semantics.html#the-multiple-attribute – Rob Johansen Oct 10 '15 at 20:21
  • @AlienBishop Actually, you just provided the reference in that link. Have a look at it again. – kojow7 Oct 10 '15 at 21:00
  • 1
    For others that are interested, boolean values are described [here](http://www.w3.org/TR/2011/WD-html5-20110525/common-microsyntaxes.html#boolean-attribute). It says: "If the attribute is present, its value must either be the empty string or a value that is an ASCII case-insensitive match for the attribute's canonical name, with no leading or trailing whitespace". That link also gives three different alternatives for creating a boolean value. As to whether attribute values should be quoted or not see [here](http://www.w3.org/html/wg/drafts/html/master/syntax.html#attributes-2). – kojow7 Oct 13 '15 at 16:15
  • So in this context `$_FILES["file"]["tmp_name"]` is a nested array (or always a nested array)? – oldboy Mar 24 '18 at 04:59
  • I wrote a library that makes dealing with `$_FILES` and `` more straight forward. Or even, multiple file fields with `multiple`. https://github.com/tvanc/files-array-organizer – tvanc Mar 07 '20 at 06:37
  • 1
    Also worth noting that the `
    ` element must have `enctype="multipart/form-data"` set.
    – Chris Wheeler Jul 02 '20 at 16:19
41

Multiple files can be selected and then uploaded using the
<input type='file' name='file[]' multiple>
The sample php script that does the uploading:

<html>
<title>Upload</title>
<?php
    session_start();
    $target=$_POST['directory'];
        if($target[strlen($target)-1]!='/')
                $target=$target.'/';
            $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='';
            }
    header("location:../../views/upload.php");
?>
</html>

The selected files are received as an array with

$_FILES['file']['name'][0] storing the name of first file.
$_FILES['file']['name'][1] storing the name of second file.
and so on.

rjv
  • 6,058
  • 5
  • 27
  • 49
  • is there any way to access the file paths of each file with JS when uploading multiple files? for instance, for single files you can simply query fileInput.value, but i've noticed that when multiple files are selected fileInput.value still only outputs one path... – oldboy Apr 08 '18 at 18:55
7

this simple script worked for me.

<?php

foreach($_FILES as $file){
  //echo $file['name']; 
  echo $file['tmp_name'].'</br>'; 
  move_uploaded_file($file['tmp_name'], "./uploads/".$file["name"]);
}

?>
Rohit Mandiwal
  • 10,258
  • 5
  • 70
  • 83
6

HTML

  1. create div with id='dvFile';

  2. create a button;

  3. onclick of that button calling function add_more()

JavaScript

function  add_more() {
  var txt = "<br><input type=\"file\" name=\"item_file[]\">";
  document.getElementById("dvFile").innerHTML += txt;
}

PHP

if(count($_FILES["item_file"]['name'])>0)
 { 
//check if any file uploaded
 $GLOBALS['msg'] = ""; //initiate the global message
  for($j=0; $j < count($_FILES["item_file"]['name']); $j++)
 { //loop the uploaded file array
   $filen = $_FILES["item_file"]['name']["$j"]; //file name
   $path = 'uploads/'.$filen; //generate the destination path
   if(move_uploaded_file($_FILES["item_file"]['tmp_name']["$j"],$path)) 
{
   //upload the file
    $GLOBALS['msg'] .= "File# ".($j+1)." ($filen) uploaded successfully<br>";
    //Success message
   }
  }
 }
 else {
  $GLOBALS['msg'] = "No files found to upload"; //No file upload message 
}

In this way you can add file/images, as many as required, and handle them through php script.

bool.dev
  • 17,508
  • 5
  • 69
  • 93
kdniazi
  • 77
  • 1
  • 1
  • 1
    _Replace this_ document.getElementById("dvFile").innerHTML += txt; **with** $( "#dvFile" ).append(txt ); **it will save your attachment** – Rahul rajoria Mar 10 '17 at 17:55
  • This answer is obsolote (and too complicated for something so simple, in my opinion). For a correct answer take look at @rjv's – Alonso Urbano Oct 05 '17 at 13:12
  • @VladimirNul is there any way to access the file paths of each file with JS when uploading multiple files? for instance, for single files you can simply query `fileInput.value`, but i've noticed that when multiple files are selected `fileInput.value` still only outputs one path... – oldboy Apr 08 '18 at 18:55
  • @Anthony it sounds like you are doing that in javascript, I don't see the point. Please check rjv's answer. – Alonso Urbano Apr 09 '18 at 18:38
5

Here is a function I wrote which returns a more understandable $_FILES array.

function getMultiple_FILES() {
    $_FILE = array();
    foreach($_FILES as $name => $file) {
        foreach($file as $property => $keys) {
            foreach($keys as $key => $value) {
                $_FILE[$name][$key][$property] = $value;
            }
        }
    }
    return $_FILE;
}
Cheejyg
  • 336
  • 4
  • 12
5

It's not that different from uploading one file - $_FILES is an array containing any and all uploaded files.

There's a chapter in the PHP manual: Uploading multiple files

If you want to enable multiple file uploads with easy selection on the user's end (selecting multiple files at once instead of filling in upload fields) take a look at SWFUpload. It works differently from a normal file upload form and requires Flash to work, though. SWFUpload was obsoleted along with Flash. Check the other, newer answers for the now-correct approach.

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
4

Simple is that, just count the files array first, then in while loop you can easily do this like

$count = count($_FILES{'item_file']['name']);

now you got total number of files right.

In while loop do like this:

$i = 0;
while($i<$count)
{
    Upload one by one like we do normally
    $i++;
}
bensiu
  • 24,660
  • 56
  • 77
  • 117
Nick
  • 49
  • 1
  • 1
4
<!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=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<?php
$max_no_img=4; // Maximum number of images value to be set here

echo "<form method=post action='' enctype='multipart/form-data'>";
echo "<table border='0' width='400' cellspacing='0' cellpadding='0' align=center>";
for($i=1; $i<=$max_no_img; $i++){
echo "<tr><td>Images $i</td><td>
<input type=file name='images[]' class='bginput'></td></tr>";
}

echo "<tr><td colspan=2 align=center><input type=submit value='Add Image'></td></tr>";
echo "</form> </table>";
while(list($key,$value) = each($_FILES['images']['name']))
{
    //echo $key;
    //echo "<br>";
    //echo $value;
    //echo "<br>";
if(!empty($value)){   // this will check if any blank field is entered
$filename =rand(1,100000).$value;    // filename stores the value

$filename=str_replace(" ","_",$filename);// Add _ inplace of blank space in file name, you can remove this line

$add = "upload/$filename";   // upload directory path is set
//echo $_FILES['images']['type'][$key];     // uncomment this line if you want to display the file type
//echo "<br>";                             // Display a line break
copy($_FILES['images']['tmp_name'][$key], $add); 
echo $add;
    //  upload the file to the server
chmod("$add",0777);                 // set permission to the file.
}
}
?>
</body>
</html>
Prix
  • 19,417
  • 15
  • 73
  • 132
muaz khalid
  • 49
  • 1
  • 1
2

I run foreach loop with error element, look like

 foreach($_FILES['userfile']['error'] as $k=>$v)
 {
    $uploadfile = 'uploads/'. basename($_FILES['userfile']['name'][$k]);
    if (move_uploaded_file($_FILES['userfile']['tmp_name'][$k], $uploadfile)) 
    {
        echo "File : ", $_FILES['userfile']['name'][$k] ," is valid, and was                      successfully uploaded.\n";
    }

    else 
    {
        echo "Possible file : ", $_FILES['userfile']['name'][$k], " upload attack!\n";
    }   

 }
HCV
  • 41
  • 4
1

Just came across the following solution:

http://www.mydailyhacks.org/2014/11/05/php-multifile-uploader-for-php-5-4-5-5/

it is a ready PHP Multi File Upload Script with an form where you can add multiple inputs and an AJAX progress bar. It should work directly after unpacking on the server...

richie
  • 7
  • 1
  • 2
0

We can easy to upload multiple files using php by using the below script.

Download Full Source code and preview

<?php
if (isset($_POST['submit'])) {
    $j = 0; //Variable for indexing uploaded image 

 $target_path = "uploads/"; //Declaring Path for uploaded images
    for ($i = 0; $i < count($_FILES['file']['name']); $i++) {//loop to get individual element from the array

        $validextensions = array("jpeg", "jpg", "png");  //Extensions which are allowed
        $ext = explode('.', basename($_FILES['file']['name'][$i]));//explode file name from dot(.) 
        $file_extension = end($ext); //store extensions in the variable

  $target_path = $target_path . md5(uniqid()) . "." . $ext[count($ext) - 1];//set the target path with a new name of image
        $j = $j + 1;//increment the number of uploaded images according to the files in array       

   if (($_FILES["file"]["size"][$i] < 100000) //Approx. 100kb files can be uploaded.
                && in_array($file_extension, $validextensions)) {
            if (move_uploaded_file($_FILES['file']['tmp_name'][$i], $target_path)) {//if file moved to uploads folder
                echo $j. ').<span id="noerror">Image uploaded successfully!.</span><br/><br/>';
            } else {//if file was not moved.
                echo $j. ').<span id="error">please try again!.</span><br/><br/>';
            }
        } else {//if file size and file type was incorrect.
            echo $j. ').<span id="error">***Invalid file Size or Type***</span><br/><br/>';
        }
    }
}
?>
Merbin Joe
  • 611
  • 6
  • 27
0
$property_images = $_FILES['property_images']['name'];
    if(!empty($property_images))
    {
        for($up=0;$up<count($property_images);$up++)
        {
            move_uploaded_file($_FILES['property_images']['tmp_name'][$up],'../images/property_images/'.$_FILES['property_images']['name'][$up]);
        }
    }
Vishnu Bhadoriya
  • 1,655
  • 1
  • 20
  • 28
0
extract($_POST);
    $error=array();
    $extension=array("jpeg","jpg","png","gif");
    foreach($_FILES["files"]["tmp_name"] as $key=>$tmp_name)
            {
                $file_name=$_FILES["files"]["name"][$key];
                $file_tmp=$_FILES["files"]["tmp_name"][$key];
                $ext=pathinfo($file_name,PATHINFO_EXTENSION);
                if(in_array($ext,$extension))
                {
                    if(!file_exists("photo_gallery/".$txtGalleryName."/".$file_name))
                    {
                        move_uploaded_file($file_tmp=$_FILES["files"]["tmp_name"][$key],"photo_gallery/".$txtGalleryName."/".$file_name);
                    }
                    else
                    {
                        $filename=basename($file_name,$ext);
                        $newFileName=$filename.time().".".$ext;
                        move_uploaded_file($file_tmp=$_FILES["files"]["tmp_name"][$key],"photo_gallery/".$txtGalleryName."/".$newFileName);
                    }
                }
                else
                {
                    array_push($error,"$file_name, ");
                }
            }

and you must check your HTML code

<form action="create_photo_gallery.php" method="post" enctype="multipart/form-data">
    <table width="100%">
        <tr>
            <td>Select Photo (one or multiple):</td>
            <td><input type="file" name="files[]" multiple/></td>
        </tr>
        <tr>
            <td colspan="2" align="center">Note: Supported image format: .jpeg, .jpg, .png, .gif</td>
        </tr>
        <tr>
            <td colspan="2" align="center"><input type="submit" value="Create Gallery" id="selectedButton"/></td>
        </tr>
    </table>
</form>

Nice link on:

PHP Single File Uploading with vary basic explanation.

PHP file uploading with the Validation

PHP Multiple Files Upload With Validation Click here to download source code

PHP/jQuery Multiple Files Upload With The ProgressBar And Validation (Click here to download source code)

How To Upload Files In PHP And Store In MySql Database (Click here to download source code)

Kalpesh Rajai
  • 2,040
  • 27
  • 39
0

This is what worked for me. I had to upload files, store filenames and I had additional inof from input fields to store as well and one record per multiple file names. I used serialize() then added that to the main sql query.

  class addReminder extends dbconn {
    public function addNewReminder(){

           $this->exdate = $_POST['exdate'];
           $this->name = $_POST['name'];
           $this->category = $_POST['category'];
           $this->location = $_POST['location'];
           $this->notes = $_POST['notes'];



           try {

                     if(isset($_POST['submit'])){
                       $total = count($_FILES['fileUpload']['tmp_name']);
                       for($i=0;$i<$total;$i++){
                         $fileName = $_FILES['fileUpload']['name'][$i];
                         $ext = pathinfo($fileName, PATHINFO_EXTENSION);
                         $newFileName = md5(uniqid());
                         $fileDest = 'filesUploaded/'.$newFileName.'.'.$ext;
                         $justFileName = $newFileName.'.'.$ext;
                         if($ext === 'pdf' || 'jpeg' || 'JPG'){
                             move_uploaded_file($_FILES['fileUpload']['tmp_name'][$i], $fileDest);
                             $this->fileName = array($justFileName);
                             $this->encodedFileNames = serialize($this->fileName);
                             var_dump($this->encodedFileNames);
                         }else{
                           echo $fileName . ' Could not be uploaded. Pdfs and jpegs only please';
                         }
                       }

                    $sql = "INSERT INTO reminders (exdate, name, category, location, fileUpload, notes) VALUES (:exdate,:name,:category,:location,:fileName,:notes)";
                    $stmt = $this->connect()->prepare($sql);
                    $stmt->bindParam(':exdate', $this->exdate);
                    $stmt->bindParam(':name', $this->name);
                    $stmt->bindParam(':category', $this->category);
                    $stmt->bindParam(':location', $this->location);
                    $stmt->bindParam(':fileName', $this->encodedFileNames);
                    $stmt->bindParam(':notes', $this->notes);
                    $stmt->execute();
                  }

           }catch(PDOException $e){
             echo $e->getMessage();
           }
      }
    }