PHP上传多个文件只上传1个文件

i edited this code alot of times (im noob whit php) and my problem is upload multiples files with this code. i can upload only 1 file.

Here is the code:

<?php
/**
 * uploadFile()
 * 
 * @param string $file_field name of file upload field in html form
 * @param bool $check_image check if uploaded file is a valid image
 * @param bool $random_name generate random filename for uploaded file
 * @return array
 */
function uploadFile ($file_field = null, $check_image = false, $random_name = false) {

  //Config Section    
  //Set file upload path
  $path = 'c:/xampp/htdocs/'; //with trailing slash
  //Set max file size in bytes
  $max_size = 1000000;
  //Set default file extension whitelist
  $whitelist_ext = array('jpg','png','gif');
  //Set default file type whitelist
  $whitelist_type = array('image/jpeg', 'image/png','image/gif');

  //The Validation
  // Create an array to hold any output
  $out = array('error'=>null);

  if (!$file_field) {
    $out['error'][] = "Please specify a valid form field name";           
  }

  if (!$path) {
    $out['error'][] = "Please specify a valid upload path";               
  }

  if (count($out['error'])>0) {
    return $out;
  }

  //Make sure that there is a file
  if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) {

    // Get filename
    $file_info = pathinfo($_FILES[$file_field]['name']);
    $name = $file_info['filename'];
    $ext = $file_info['extension'];

    //Check file has the right extension           
    if (!in_array($ext, $whitelist_ext)) {
      $out['error'][] = "Invalid file Extension";
    }

    //Check that the file is of the right type
    if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) {
      $out['error'][] = "Invalid file Type";
    }

    //Check that the file is not too big
    if ($_FILES[$file_field]["size"] > $max_size) {
      $out['error'][] = "File is too big";
    }

    //If $check image is set as true
    if ($check_image) {
      if (!getimagesize($_FILES[$file_field]['tmp_name'])) {
        $out['error'][] = "Uploaded file is not a valid image";
      }
    }

    //Create full filename including path
    if ($random_name) {
      // Generate random filename
      $tmp = str_replace(array('.',' '), array('',''), microtime());

      if (!$tmp || $tmp == '') {
        $out['error'][] = "File must have a name";
      }     
      $newname = $tmp.'.'.$ext;                                
    } else {
        $newname = $name.'.'.$ext;
    }

    //Check if file already exists on server
    if (file_exists($path.$newname)) {
      $out['error'][] = "A file with this name already exists";
    }

    if (count($out['error'])>0) {
      //The file has not correctly validated
      return $out;
    } 

    if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) {
      //Success
      $out['filepath'] = $path;
      $out['filename'] = $newname;
      return $out;
    } else {
      $out['error'][] = "Server Error!";
    }

  } else {
    $out['error'][] = "No file uploaded";
    return $out;
  }      
}
?>
<?php
if (isset($_POST['submit'])) {
  $file = uploadFile('file', true, true);
  if (is_array($file['error'])) {
    $message = '';
    foreach ($file['error'] as $msg) {
      $message .= '<p>'.$msg.'</p>';    
    }
  } else {
    $message = "File uploaded successfully";
  }
  echo $message;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
<input name="file" type="file" size="20" multiple="multiple" />
<input name="submit" type="submit" value="Upload files" />
</form>

please help me understand... i know i must use foreach

You have to use foreach loop to upload multiple files. in framework also thy have provided components with same facility (i.e by using foreach loop).

my suggestion is

  1. Start a loop: foreach ($_FILES[$file_field] as $file) { where you have // Get filename string
  2. Close it with } in the end of the function
  3. Change all $_FILES[$file_field] to $file inside it

And, of course, input must have multiple attribute as Sherin Jose said (tut), but now it's fully supported only by 8.27% of browsers, so you'd better add more inputs with JS, like

<input type="file" name="file[]" />
<input type="file" name="file[]" />
...

and loop them in the same way

To successfully send multiple files from you're browser, you need your inputs to pass an array to PHP. This is done by appending [] to the end of your <input>s name:

<input type="file" name="filesToUpload[]" multiple>

Processing these files is the tricky part. PHP handles file uploads differently than it would handle other POST or GET data provided in an array. File uploads have a metadata key inserted between the input's name, and the index of the file that was uploaded. So $_FILES['filesToUpload']['name'][0] will get the name of the first file, and $_FILES['filesToUpload']['name'][1] will get the name of the second file... and so on.

Because of this foreach is absolutely the wrong loop to use. You will end up processing each piece of metadata on it's own, without any context. That's dreafully unnatural.

Let's get the index of each file and process one file at a time instead. We'll use a for loop for this. This is an entirely self contained, functioning example of a user uploading multiple files to a folder on the server:

<?php
/* 
 * sandbox.php
 */

if (isset($_POST['submit'])) {

    // We need to know how many files the user actually uploaded.
    $numberOfFilesUploaded = count($_FILES['filesToUpload']['name']);

    for ($i = 0; $i < $numberOfFilesUploaded; $i++) {
        // Each iteration of this loop contains a single file.
        $fileName = $_FILES['filesToUpload']['name'][$i];
        $fileTmpName = $_FILES['filesToUpload']['tmp_name'][$i];
        $fileSize = $_FILES['filesToUpload']['size'][$i];
        $fileError = $_FILES['filesToUpload']['error'][$i];
        $fileType = $_FILES['filesToUpload']['type'][$i];

        // PHP has saved the uploaded file as a temporary file which PHP will 
        // delete after the script has ended.
        // Let's move the file to an output directory so PHP will not delete it.
        move_uploaded_file($fileTmpName, './output/' . $fileName);
    }
}

?>

<form method="post" enctype="multipart/form-data">
                              <!-- adding [] Allows us to upload multiple files -->
    <input type="file" name="filesToUpload[]" multiple>
    <input type="submit" name="submit"/>Submit
</form>

To run this example, your files should look like this

enter image description here

You can startup the PHP builtin webserver with:

$ php -S localhost:8000

Then going to http://localhost:8000/sandbox.php will run the example.


Important note: The above example does not do any validation. You will need to validate that all the uploaded files are safe.