简体   繁体   中英

PHP Upload multiple files only upload 1 file

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 should use the file field as an array like file[]

<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>

Change the code as above and try

As others have pointed out, you need to change your upload field name to ie. files[] (include the sqaure brackets after the name). This is relevant as it tells PHP that it should treat the field as an array.

Additionally, in the code, you may use foreach() to access the uploaded files like this:

foreach ($_FILES['field_name'] as $file)

(obviously, yout html field would be names field_name[] in this case) This will return one array in each of its five iterations, giving you information about all the files you've sent. For instance, if you have sent two files, it may look like this:

    ["name"]=>
    array(2) {
      [0]=>
      string(5) "dir.c"
      [1]=>
      string(10) "errcodes.h"
    }
    ["type"]=>
    array(2) {
      [0]=>
      string(11) "text/x-csrc"
      [1]=>
      string(11) "text/x-chdr"
    }
    ["tmp_name"]=>
    array(2) {
      [0]=>
      string(14) "/tmp/phpP1iz5A"
      [1]=>
      string(14) "/tmp/phpf31fzn"
    }
    ["error"]=>
    array(2) {
      [0]=>
      int(0)
      [1]=>
      int(0)
    }
    ["size"]=>
    array(2) {
      [0]=>
      int(511)
      [1]=>
      int(38)
    }
  }

It's important to understand that PHP will categorize those not into files and then give each its properties, but rather will list the properties for all the files.

I hope it's clear now.

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

在此处输入图片说明

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.

You have to use foreach loop to upload multiple files. in framework also thy have provided components with same facility (ie 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM