3

I got this galley working about 65% of where I want it to be. I was wondering if someone could look at the following code and tell me how to upload multiple images to my gallery.

Here is the code.

Simple admin form code:

    <form enctype="multipart/form-data" action="uploader.php" method="POST">


        Category: <select class="text" name="dataType[]">
        <option value="treeremoval" selected="selected">treeremoval</option>
        <option value="treetrimming" >treetrimming</option>
        <option value="treebracing" >treebracing</option>
        <option value="stumpgrinding" >stumpgrinding</option>
        <option value="firewood" >firewood</option>
        <option value="cleanup" >cleanup</option>
        </select>
<br /><br />

    Caption: <input type="text" name="title[]">
<br /><br />

Image to upload: <input type="file" name="image[]" />
<br /><br />






        Category: <select class="text" name="dataType[]">
        <option value="treeremoval" selected="selected">treeremoval</option>
        <option value="treetrimming" >treetrimming</option>
        <option value="treebracing" >treebracing</option>
        <option value="stumpgrinding" >stumpgrinding</option>
        <option value="firewood" >firewood</option>
        <option value="cleanup" >cleanup</option>
        </select>
<br /><br />

    Caption: <input type="text" name="title[]">
<br /><br />

Image to upload: <input type="file" name="image[]" />
<br /><br />



    <input type="submit" value="Upload">
</form>

uploader.php code:


    <?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");

$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);

$fileData = pathinfo(basename($_FILES["image"]["name"][$i]));

$fileName = uniqid() . '.' . $fileData['extension'][$i];

$target_path = ($_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName);


for($i=0;$i<count($_FILES["image"]["name"]);$i++){

 $dataType = mysql_real_escape_string($_POST["dataType"][$i]);  // get the dataType with the same key - $i
    $title = mysql_real_escape_string($_POST["title"][$i]);   // get the title with the same key - $i

    $fileData = pathinfo(basename($_FILES["image"]["name"][$i]));
while(file_exists($target_path))
{
    $fileName = uniqid() . '.' . $fileData['extension'];
    $target_path = ($_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName);
}

 if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path))
    {    // The file is in the images/gallery folder. Insert record into database by
    // executing the following query:
     $sql="INSERT INTO images (data_type, title, file_name)"."VALUES('$dataType','$title','$fileName')";
     $retval = mysql_query($sql);



echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
     <a href='index.php'>Add another image</a><br />";


}
else
{
 echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
    }
} // close your foreach
?>

I tried duplicating the form code 4 times, but it would only upload 1 image to the gallery.

Any help would be greatly appreciated.

Thank You!

daugaard47
  • 1,726
  • 5
  • 39
  • 74
  • add multiple `` each with a unique name –  Jul 11 '13 at 21:19
  • You can set this in a relatively simple way... I think it's on the input type="file", where you put a data-type... or something? Then your $_FILES will be an array of several files. We did this at school, a single input for multiple files, but we used a teacher template, so I forgot. If you can't find notify me and I'll search through my files. – Ariane Jul 11 '13 at 21:20
  • @Dagon could you explain a little more in detail. Sorry kinda new at this type of coding. – daugaard47 Jul 11 '13 at 21:27
  • @Ariane I like the sound of your solution, if you can find that file I would appreciate it. you can email me at daugaard47@gmail.com – daugaard47 Jul 11 '13 at 21:27

4 Answers4

5

In your form, add multiple file inputs. One way is to use an array name - image[]

Image to upload: <input type="file" name="image[]" /><br />
Image to upload: <input type="file" name="image[]" /><br />
Image to upload: <input type="file" name="image[]" /><br />
....  // as many as you want. Just be aware of upload_max_filesize, memory_limit, post_max_size etc.
<br /> 

Then in your uploader.php, wrap your file upload code with a for loop

for($i=0;$i<count($_FILES["image"]["name"]);$i++){

    $fileData = pathinfo(basename($_FILES["image"]["name"][$i]));

     ...

    if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path))
    {
      ...

      echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />";

    }
    else
    {
     echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
    }
} // close your foreach

the manual has a great section on common pitfalls when uploading files, especially multiple. http://www.php.net/manual/en/features.file-upload.common-pitfalls.php


If you want to do multiple of the others, it can be done the same way (I abbreviated the selects to reduce copy/paste) -

<form enctype="multipart/form-data" action="uploader.php" method="POST">

    // 1st set
    Category: <select class="text" name="dataType[]" />
    ...
    </select><br />
    <br />        

    Caption: <input type="text" name="title[]" /><br />
    <br />

    Image to upload: <input type="file" name="image[]" /><br />
    <br /> 

    // 2nd set
    Category: <select class="text" name="dataType[]" />
    ...
    </select><br />
    <br />        

    Caption: <input type="text" name="title[]" /><br />
    <br />

    Image to upload: <input type="file" name="image[]" /><br />
    <br />  

   // and so on, as many as you want  
   ...
    <input type="submit" value="Upload">
</form>

and your php, put the for loop around all the elements

for($i=0;$i<count($_FILES["image"]["name"]);$i++){

    $dataType = mysql_real_escape_string($_POST["dataType"][$i]);  // get the dataType with the same key - $i
    $title = mysql_real_escape_string($_POST["title"][$i]);   // get the title with the same key - $i

    $fileData = pathinfo(basename($_FILES["image"]["name"][$i]));

     ...

    if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path))
    {
      ...

      echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />";

    }
    else
    {
     echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
    }
} // close your foreach

edit
you are almost there. Remove the duplicate code above the for loop. Remove basename(), as this is causing your extension to fail, and pathinfo() will return the ['basename'].

<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");

for($i=0;$i<count($_FILES["image"]["name"]);$i++){
  if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
    $dataType = mysql_real_escape_string($_POST["dataType"][$i]);
    $title = mysql_real_escape_string($_POST["title"][$i]);

    $fileData = pathinfo($_FILES["image"]["name"][$i]);

    $fileName = uniqid() . '.' . $fileData['extension'];
    $target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;

    while(file_exists($target_path)){
       $fileName = uniqid() . '.' . $fileData['extension'];
       $target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
    }     

  if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){    // The file is in the images/gallery folder. 
    // Insert record into database by executing the following query:
     $sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
     $retval = mysql_query($sql);

    echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
     <a href='index.php'>Add another image</a><br />";
  }
  else
  {
   echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
    }
  }
} // close your foreach
?>
Sean
  • 12,443
  • 3
  • 29
  • 47
  • I apologize for being uneducated on this, I realize the answer is right in front of me, but when I tried it out it through up many errors. Could you use the code I provided and modify it for me. Just not sure where to start the foreach script...? – daugaard47 Jul 11 '13 at 21:59
  • I did use your code. I did not want to copy/paste all of it, so I use an abbreviation `...` to show what you should not need to change. Keep you code, but just add/edit the lines that I showed. – Sean Jul 11 '13 at 22:01
  • you can also read about it in the php manual - http://php.net/manual/en/features.file-upload.multiple.php – Sean Jul 11 '13 at 22:04
  • While rereading my answer, I realize I was a little off. Instead of `foreach($_FILES['image'] as $files)` you need to do a for loop - `for($i=0;$i – Sean Jul 11 '13 at 22:11
  • @user1666456 Not as I had it. Instead of `foreach($_FILES['image'] as $files)`, I think it would have to be `foreach($_FILES['image']['name'] as $key => $value)`, and then use that key - `$_FILES["image"]["name"][$key]`. The original way I had it would have looped through the `$_FILES` array - `[name],[type],[tmp_name],[size],[error]`, and not the array of files. – Sean Jul 11 '13 at 22:23
  • Okay I got this to work at least adding multiple images files, but It doesn't bring in the other data in need. Category/dataType and Caption / title. I tried adding the [ ] to the end of dataType and title, but that didn't seem to work or I messed it up on the uploader script. How would I bring over that info with the multiple images? – daugaard47 Jul 12 '13 at 01:05
  • I have update with how to do multiple `dataType` and `title`, which is very similar to the files. – Sean Jul 12 '13 at 03:20
  • That worked great, but I get these warnings: Warning: mysql_real_escape_string() expects parameter 1 to be string, array given in C:\xampp\htdocs\bgtree.com\admin\uploader.php on line 4 Warning: mysql_real_escape_string() expects parameter 1 to be string, array given in C:\xampp\htdocs\bgtree.com\admin\uploader.php on line 5 Warning: basename() expects parameter 1 to be string, array given in C:\xampp\htdocs\bgtree.com\admin\uploader.php on line 7 Notice: Undefined index: extension in C:\xampp\htdocs\bgtree.com\admin\uploader.php on line 9 – daugaard47 Jul 12 '13 at 03:54
  • Also the files uploaded ,but on my second image it didn't give it an extension. Any idea why that might be? I'm using this to rename my files. `$fileName = uniqid() . '.' . $fileData['extension'];` If I can get that sorted out I'll be in good shape. – daugaard47 Jul 12 '13 at 03:57
  • Make sure that you are adding the key - `[$i]` - `$_POST["dataType"][$i]`, `$_POST["title"][$i]`. If you leave it off - `$_POST["dataType"]`, `$_POST["title"]` you are using the array. – Sean Jul 12 '13 at 03:57
  • Same thing with the `basename()` warning. Make sure you specify the key `basename($_FILES["image"]["name"][$i])`. without the `[$i]` it is trying to access the array not the string name, and so it will also cause the extension to fail / not set the index `extension`. – Sean Jul 12 '13 at 04:02
  • Okay I tried adding the `[$i])` to the place you told me, but still not getting a file extension on the 2nd image. I updated my code to show you what I'm using. Can you see any errors in the uploader code? – daugaard47 Jul 12 '13 at 04:19
  • I think you are just about there. Look at the **edit** that I just added to my answer. Your form looks good, there are just a couple things with your php. This time I copy/paste your whole code, so it should help you finalize your code. – Sean Jul 12 '13 at 05:15
  • @Sean Your edited code worked flawlessly! Thank you so much. I really learned a lot from you today. Really appreciate the help. Now for my next mission, learn how to auto resize and crop the images to 720w X 482h. I've been looking into a script called wide image. Do you have any tricks up your sleeve for this. lol I'm going to start a new thread for this one if / when I get lost. Thanks again man! -Chris – daugaard47 Jul 12 '13 at 05:28
  • Awesome, glad we were able to get all to work properly. I don't do much in image resizing, so I don't have any recommendations. But if you run into issues I am always willing/able to help debug/troubleshoot. – Sean Jul 12 '13 at 05:46
  • @Sean I might take you up on that offer, my email is listed in my profile. If you dont mind, send me an email so I have yours and I'll holler at you if I have another post on here, if I think you could help. Thanks again. Talk to you later. – daugaard47 Jul 12 '13 at 05:55
2

Apparently, an HTML5 feature that's sadly not supported in Internet Explorer before version 10(!) allows you to do this:

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

This is also valid:

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

(The end slash is facultative, but I like self-closing tags to have a slash, so I decided to put slashes.)

However there are JavaScript, etc. tools that apparently widen the compatibility. Like this Jquery thing. blueimp.github.io/jQuery-File-Upload

(Source: How to select multiple files with <input type="file">?)

(I was sure there was a simpler, IE-compatible method, but maybe I imagined it. Either way, I apparently left the upload documentation from my teacher at school before leaving for the holidays, so I can't know for sure.)

So... yeah. You have this multiple="multiple" input that does the job. But it's definitely not compatible enough for your needs. Because, you know, not many people have IE 10, and there's a limit to ditching IE. From there on, you have a few choices.

  1. Check for compatibility with multi-file inputs using a tool such as Modernizr, and if the browser is not compatible, then instead of it, you'll display several single-file inputs. Or maybe just one, and then, you'd add another through Javascript when the previous one is used.

  2. Look into that jQuery plugin or other similar tools to "force" browsers to be compatible with your multi-file input.

Usage example a multi-file input:

HTML:

<form method="post" action="upload.php" enctype="multipart/form-data">
    <input name="uploads[]" type="file" multiple="multiple" />
    <input type="submit" value="Send" />
</form>

Then in PHP, all your files will be stored where you usually find your single file, except that it'll be an array, now, and you'll access it by adding an additional layer of square brackets. For example, $_FILES['uploads']['name'][0] is your first file.

The following code will allow you to iterate over every single file. Of course, this code only displays every file name, but you can change the content of the loop.

foreach ($_FILES['uploads']['name'] as $filename) {
    echo '<li>' . $filename . '</li>';
}

And inside this loop, you'll process to upload each file as you normally would for a single file.

(Source: http://css-tricks.com/snippets/html/multiple-file-input/)

Community
  • 1
  • 1
Ariane
  • 393
  • 4
  • 14
1

The easiest way is to add multiple file inputs (in one form) with the same name, adding square brackets:

<input type="file" name="image[]">

You can then access the files by adding an incremental number:

$_FILES["image"]["name"][0] 

So you put the whole after-upload process into a loop iterating through the files. Please note that in case you do not always submit an image with each file input, some variables (=inputs) will stay empty and you need to change your error handling to not showing an error then. I'd do it like this:

if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)) {
     //processing...
} else if (!empty($_FILES["image"]["name"][$i]) {
     //error
}
user1666456
  • 351
  • 1
  • 9
0

I don't know if I can post links, but i found this looking for a system that upload multiples files, and want to share with all other that are looking for this too.

MySQL

CREATE TABLE `upload_data` (
  `ID` int(5) NOT NULL AUTO_INCREMENT,
  `USER_CODE` int(4) unsigned zerofill NOT NULL,
  `FILE_NAME` varchar(200) NOT NULL,
  `FILE_SIZE` varchar(200) NOT NULL,
  `FILE_TYPE` varchar(200) NOT NULL,
  PRIMARY KEY (`ID`)
)

PHP

<?php
if(isset($_FILES['files'])){
    $errors= array();
    foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
        $file_name = $key.$_FILES['files']['name'][$key];
        $file_size =$_FILES['files']['size'][$key];
        $file_tmp =$_FILES['files']['tmp_name'][$key];
        $file_type=$_FILES['files']['type'][$key];  
        if($file_size > 2097152){
            $errors[]='File size must be less than 2 MB';
        }       
        $query="INSERT into upload_data (`USER_ID`,`FILE_NAME`,`FILE_SIZE`,`FILE_TYPE`) VALUES('$user_id','$file_name','$file_size','$file_type'); ";
        $desired_dir="user_data";
        if(empty($errors)==true){
            if(is_dir($desired_dir)==false){
                mkdir("$desired_dir", 0700);        // Create directory if it does not exist
            }
            if(is_dir("$desired_dir/".$file_name)==false){
                move_uploaded_file($file_tmp,"user_data/".$file_name);
            }else{                                  //rename the file if another one exist
                $new_dir="user_data/".$file_name.time();
                 rename($file_tmp,$new_dir) ;               
            }
            mysql_query($query);            
        }else{
                print_r($errors);
        }
    }
    if(empty($error)){
        echo "Success";
    }
}
?>


<form action="" method="POST" enctype="multipart/form-data">
    <input type="file" name="files[]" multiple/>
    <input type="submit"/>
</form>

That's it! Hope help someone ^^ Complete explanations and all credits to: http://techstream.org/Web-Development/PHP/Multiple-File-Upload-with-PHP-and-MySQL

Felipe Lima
  • 443
  • 1
  • 10
  • 19