I am trying to adjust my upload code to handle multiple uploads at the same time, I have searched and found all kinds of code that says to wrap my current upload scrypt inside of it and just change my file system to an array but every time I do I get an error so here is the code I am working with:

session_start();
error_reporting(E_ALL);

//foreach($_FILES['file'] AS $file)
//{
$allowedExts = array("jpg", "jpeg", "gif", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000000)
&& in_array($extension, $allowedExts))
{
  if ($_FILES["file"]["error"] > 0)
  {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
  }else
  {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";

    if (file_exists("pics/" . $_FILES["file"]["name"]))
    {
      echo $_FILES["file"]["name"] . " already exists. ";
    }else
    {
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "pics/" . $_FILES["file"]["name"]);

       $path = $_FILES["file"]["name"];

      $sql = "INSERT INTO uploads (ref_id, name) VALUES('$_POST[refID]', '$path')";
      if (!mysql_query($sql,$con))
      {
          die('Error: ' . mysql_error());
      }else
      {
         ?>
          <script type="text/javascript">
          alert("Inventory successfully updated, Thank You");
          document.location.href="picUploads.php";
          </script>
        <?php
     }
    }
  }
}else
{
  echo "Invalid file";
}
//}

the foreach statment is commented out because I wanted to check and make sure again that the code worked for a single upload which it does. here is the form for a single upload

<!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>Photo Upload</title>
</head>

<body  onUnload="window.addEventListener("unload", invalidateBackCache, true)">
<center><h1>UPLOAD PICTURES</h1></center>
<form action="upload.php" method="post"
enctype="multipart/form-data">
<input type="hidden" name="refID" value=<?php echo $_POST['refID']; ?> /><br />
<label for="file">Pictures to be uploaded:</label><br />
<input name="file" type="file" /><br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

when I change <input name="file" type="file" /> to <input name="file[]" type="file" /> adding another couple of input fields and wrapping my upload script in the foreach code I get an error that says there is an error on line 10 of my upload.php which is this line $extension = end(explode(".", $_FILES["file"]["name"])); the error says that explode expects the forst paramiter to be an array and end expects the second paramiter to be a string, I understand what the error is telling me but I am not sure how to adjust the code to give it what it is wanting.

Recommended Answers

All 12 Replies

sorry I was wrong this is the error I keep getting

Warning: explode() expects parameter 2 to be string, array given in /home/test.com/upload.php on line 10
Warning: end() expects parameter 1 to be array, null given in /home/test.com/upload.php on line 10

ok got rid of those errors by changing this

$extension = end(explode(".", $_FILES["file"]["name"]))

to this

$extension = end(explode(".", $_FILES["file[]"]["name"]))

however now I am getting this error

Notice: Undefined index: file[] in /home/test.com/upload.php on line 10

Member Avatar for diafol

Could I suggest that you use a real check not a filename check. Any old nasty file could be given a .png or whatever extension.

With multiple file fields with the same name array, e.g. name="myfile[]"

For 3 uploaded files, you will get:

$_FILES['myfile']['name'][0]...
$_FILES['myfile']['name'][1]...
$_FILES['myfile']['name'][2]...

$_FILES['myfile']['tmp_name'][0]
$_FILES['myfile']['tmp_name'][1]
$_FILES['myfile']['tmp_name'][2]

Same for ['type'], ['error'], ['size']

So your $_FILES["file[]"]["name"] is meaningless.

The exif_imagetype() function: http://php.net/manual/en/function.exif-imagetype.php may be a safer bet for image type, as it actually reads part of the file.

good lookin out D I will look into that, thanks.

so then this

if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png")
|| ($_FILES["file"]["type"] == "image/jpg"))
&& ($_FILES["file"]["size"] < 20000000)

should now be

if ((exif_imagetype('image.gif') == "image/gif")
|| (exif_imagetype('image.jpeg') == "image/jpeg")
|| (exif_imagetype('image.png') == "image/png")
|| (exif_imagetype('image.jpg') == "image/jpg"))
&& ($_FILES["file"]["size"] < 20000000))
{ 'upload code here'}

corect?

yeah that doesnt work very well I got all kinds of errors thrown at me one of which was because the exif_imagetype() does not support .jpg and I need .jpg support because that is what gets uploaded onto the server most.

Member Avatar for diafol

I don't think your code is correct for exif_imagetype. Try something like this:

if (exif_imagetype('image.gif') == IMAGETYPE_GIF) {
    echo "this is a gif!!";
}elseif(exif_imagetype('image.gif') == IMAGETYPE_JPEG) {
    echo "this is a jpeg";
}

You can use either constants (as above) or the constant values themselves, e.g.

IMAGETYPE_GIF = 1
IMAGETYPE_JPEG = 2
IMAGETYPE_PNG = 3

if (exif_imagetype('image.gif') == 1) {
    echo "this is a gif!!";
}elseif(exif_imagetype('image.jpg') == 2) {
    echo "this is a jpeg";
}

it still doesnt allow for jpg uploads and those are the filetypes that are uploaded most on the site I am working on

Member Avatar for diafol

Shouldn't you be using $_FILES['file']['tmp_name'] instead of the actual filename? The filename $_FILES['file']['name'] is just a string, not a file. The file is uploaded to a temporary folder in php and named by $_FILES['file']['tmp_name'].

You'll need to use move_uploaded_file(): http://php.net/manual/en/function.move-uploaded-file.php to store the image file to your uploads directory once you've verified that the file is indeed of the correct type.

So:

if (in_array(exif_imagetype($_FILES['file']['tmp_name']), array(1,2,3) ) && $_FILES["file"]["size"] < 20000000){
    //...upload code...
}

I actually just found a really good source that fixed the problem I was having, the foreach loop was the wrong loop, I needed a for loop and to use $_FILES['file' . $i]['name'] to get it done right.

@D Thanks I will be looking more into the exif_imagetype() for future projects that need that kind of security, this one however is the back end of the website and is not going to be accessed by the general public so anyone that uploads something harmfull will be hurting themselves.

Member Avatar for diafol

not going to be accessed by the general public so anyone that uploads something harmfull will be hurting themselves

Things like that may come back to haunt you :(

only if I dont fix it, I plan to update the system once I have the code figured out at this time though I have my boss on my ass to just turn out what I have and worry about the rest later, so......I give him what I have and fix it right later on when he says I can, he's definitely no programmer and likes to pretend he knows more about it then anyone else.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.