Как я могу выбрать и загрузить несколько файлов с HTML и PHP, используя HTTP POST?

155

У меня есть опыт сделать это с использованием одного файла загрузки <input type="file">. Однако у меня возникли проблемы с загрузкой более одного за раз.

Например, я хотел бы иметь возможность выбрать серию изображений, а затем загрузить их на сервер, все сразу.

Было бы здорово использовать один элемент управления вводом файлов, если это возможно.

Кто-нибудь знает, как этого добиться? Спасибо!

stalepretzel
источник
2
Вы имеете в виду выбрать более одного файла в диалоговом окне выбора файлов или использовать несколько файловых входов?
MitMaro
Привет! Можно ли загрузить файл архива (zip, rar, tar, ...)?
sourcerebels

Ответы:

196

Это возможно в HTML5 . Пример (PHP 5.4):

<!doctype html>
<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <form method="post" enctype="multipart/form-data">
            <input type="file" name="my_file[]" multiple>
            <input type="submit" value="Upload">
        </form>
        <?php
            if (isset($_FILES['my_file'])) {
                $myFile = $_FILES['my_file'];
                $fileCount = count($myFile["name"]);

                for ($i = 0; $i < $fileCount; $i++) {
                    ?>
                        <p>File #<?= $i+1 ?>:</p>
                        <p>
                            Name: <?= $myFile["name"][$i] ?><br>
                            Temporary file: <?= $myFile["tmp_name"][$i] ?><br>
                            Type: <?= $myFile["type"][$i] ?><br>
                            Size: <?= $myFile["size"][$i] ?><br>
                            Error: <?= $myFile["error"][$i] ?><br>
                        </p>
                    <?php
                }
            }
        ?>
    </body>
</html>

Вот как это выглядит в Chrome после выбора 2 элементов в диалоговом окне файла:

выбор нескольких файлов Chrome

И вот как это выглядит после нажатия кнопки «Загрузить».

отправка нескольких файлов в PHP

Это всего лишь набросок полностью рабочего ответа. Смотрите PHP Manual: Обработка загрузки файлов для получения дополнительной информации о правильной и безопасной обработке загрузки файлов в PHP.

Марк Э. Хаас
источник
8
это проходит проверку w3c, или это должно быть multiple="multiple"?
vol7ron
10
Я верю, что это действительно так: мысльresults.com/html5-boolean-attributes . Он проходит валидатор w3c, если вы добавите <! Doctype html>.
Марк Э. Хаас
2
да, это, вероятно, проверяет HTML, но не XHTML. Хотя я все еще люблю использовать XHTML, я думаю, что люди советуют держаться от него подальше в эти дни.
vol7ron
11
Он не работает без добавления свойства имени (например name="file[]"). Я попытался отредактировать ответ , но он был отклонен.
Мишель Эйрес,
1
Спасибо @MichelAyres, я обновил свой ответ. Когда я первоначально написал это, я обратился только к части проблемы HTML, потому что были другие ответы, которые объясняли часть PHP. Со временем это стало популярным ответом, поэтому теперь я расширился, чтобы охватить как HTML, так и PHP.
Марк Э. Хаазе
94

Есть несколько вещей, которые нужно сделать, чтобы создать загрузку нескольких файлов, на самом деле это довольно просто. Вам не нужно использовать Java, Ajax, Flash. Просто создайте нормальную форму загрузки файлов, начиная с:

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

Тогда ключ к успеху;

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

НЕ забывайте эти скобки! В post_upload.php попробуйте следующее:

<?php print_r($_FILES['file']['tmp_name']); ?>

Обратите внимание, что вы получите массив с данными tmp_name, что будет означать, что вы можете получить доступ к каждому файлу с помощью третьей пары скобок с примером файла 'number':

$_FILES['file']['tmp_name'][0]

Вы можете использовать php count () для подсчета количества выбранных файлов. Гудлак виддит!

эпоксиды
источник
5
Спасибо за чаевые! это сэкономило мне столько времени +1
BPm
Это работает очень хорошо ... но у меня возникают проблемы с загрузкой этого способа в Internet Explorer (v8). Я думаю, что IE не поддерживает загрузку таким способом.
Тарик М Насим
4
Или вы можете просматривать файлы с помощью foreachвыписки без необходимости знать количество загруженных файлов ...
ygesher
Обратите внимание, что если вы используете ключ своего имени в html, например, name = "file [3]", то вам необходимо получить доступ к значению через $ _FILES ['file'] ['tmp_name'] [3], в случае, если это не очевидно.
MyStream
8

Полное решение в Firefox 5:

<html>
<head>
</head>
<body>
 <form name="uploader" id="uploader" action="multifile.php" method="POST" enctype="multipart/form-data" >
  <input id="infile" name="infile[]" type="file" onBlur="submit();" multiple="true" ></input> 
 </form>

<?php
echo "No. files uploaded : ".count($_FILES['infile']['name'])."<br>"; 


$uploadDir = "images/";
for ($i = 0; $i < count($_FILES['infile']['name']); $i++) {

 echo "File names : ".$_FILES['infile']['name'][$i]."<br>";
 $ext = substr(strrchr($_FILES['infile']['name'][$i], "."), 1); 

 // generate a random new file name to avoid name conflict
 $fPath = md5(rand() * time()) . ".$ext";

 echo "File paths : ".$_FILES['infile']['tmp_name'][$i]."<br>";
 $result = move_uploaded_file($_FILES['infile']['tmp_name'][$i], $uploadDir . $fPath);

 if (strlen($ext) > 0){
  echo "Uploaded ". $fPath ." succefully. <br>";
 }
}
echo "Upload complete.<br>";
?>

</body>
</html>
Thaps
источник
Код обрезан. Вот что выше этого: <html> <head> </head> <body> <form name="uploader" id="uploader" action="multifile.php" method="POST" enctype="multipart/form-data" > <input id="infile" name="infile[]" type="file" onBlur="submit();" multiple="true" ></input> </form>
Thaps
3
Это не работает в IE8, но тогда просто используйте настоящий браузер.
Thaps
5

Если вы хотите выбрать несколько файлов в диалоговом окне выбора файлов, которое отображается при выборе обзора, то в большинстве случаев вам не повезло. Вам нужно будет использовать Java-апплет или что-то подобное (я думаю, что есть такой, который использует небольшой флэш-файл, я обновлю, если найду его). В настоящее время ввод одного файла позволяет выбрать только один файл.

Если вы говорите об использовании нескольких файловых вводов, то не должно быть большой разницы с использованием одного. Разместите некоторый код, и я постараюсь помочь в дальнейшем.


Обновление: есть один способ использовать одну кнопку просмотра, которая использует вспышку. Я никогда не использовал это лично, но я прочитал много об этом. Я думаю, что это ваш лучший выстрел.

http://swfupload.org/

MitMaro
источник
1
Я добавил ссылку на флэш-загрузчик.
MitMaro
Я использовал swfupload fwiw - иногда это немного больно, но не так уж и сложно начать работать.
Meep3D
@Barsoom это правильно. За последние пару лет ситуация с многократной загрузкой файлов стала намного лучше. : D
MitMaro
4

во-первых, вы должны сделать такую ​​форму:

<form method="post" enctype="multipart/form-data" >
   <input type="file" name="file[]" multiple id="file"/>
   <input type="submit" name="ok"  />
</form> 

это верно . Теперь добавьте этот код под кодом формы или на любую страницу, которая вам нравится

<?php
if(isset($_POST['ok']))
   foreach ($_FILES['file']['name'] as $filename) {
    echo $filename.'<br/>';
}
?>

это легко ... закончить

Пойя Ларян
источник
1

Если вы используете несколько полей ввода, вы можете установить name = "file []" (или любое другое имя). Это поместит их в массив, когда вы загрузите их ( $_FILES['file'] = array ({file_array},{file_array]..))

Torandi
источник
1
<form action="" method="POST" enctype="multipart/form-data">
  Select image to upload:
  <input type="file"   name="file[]" multiple/>
  <input type="submit" name="submit" value="Upload Image" />
</form>

Использование цикла FOR

<?php    
  $file_dir  = "uploads";    
  if (isset($_POST["submit"])) {

    for ($x = 0; $x < count($_FILES['file']['name']); $x++) {               

      $file_name   = $_FILES['file']['name'][$x];
      $file_tmp    = $_FILES['file']['tmp_name'][$x];

      /* location file save */
      $file_target = $file_dir . DIRECTORY_SEPARATOR . $file_name; /* DIRECTORY_SEPARATOR = / or \ */

      if (move_uploaded_file($file_tmp, $file_target)) {                        
        echo "{$file_name} has been uploaded. <br />";                      
      } else {                      
        echo "Sorry, there was an error uploading {$file_name}.";                               
      }                 

    }               
  }    
?>

Использование цикла FOREACH

<?php
  $file_dir  = "uploads";    
  if (isset($_POST["submit"])) {

    foreach ($_FILES['file']['name'] as $key => $value) {                   

      $file_name   = $_FILES['file']['name'][$key];
      $file_tmp    = $_FILES['file']['tmp_name'][$key];

      /* location file save */
      $file_target = $file_dir . DIRECTORY_SEPARATOR . $file_name; /* DIRECTORY_SEPARATOR = / or \ */

      if (move_uploaded_file($file_tmp, $file_target)) {                        
        echo "{$file_name} has been uploaded. <br />";                      
      } else {                      
        echo "Sorry, there was an error uploading {$file_name}.";                               
      }                 

    }               
  }
?>
antelove
источник
0

я создал функцию php, которая используется для загрузки нескольких изображений, эта функция может загружать несколько изображений в определенную папку, а также может сохранять записи в базе данных в следующем коде $ arrayimage - это массив изображений, который отправляется через примечание формы что он не разрешит загрузку использовать несколько, но вам нужно создать другое поле ввода с тем же именем, как вы можете установить динамическое поле добавления файла, выводимое нажатием кнопки.

$ dir - это каталог, в котором вы хотите сохранить изображение. $ fields - это имя поля, которое вы хотите сохранить в базе данных.

поле базы данных должно быть в примере формата массива, если у вас есть база данных imagestore и имена полей, такие как id, name, address, то вам нужно опубликовать данные как

$fields=array("id"=$_POST['idfieldname'], "name"=$_POST['namefield'],"address"=$_POST['addressfield']);

а затем передать это поле в функцию $ fields

$ table - это имя таблицы, в которой вы хотите хранить данные.

function multipleImageUpload($arrayimage,$dir,$fields,$table)
{
    //extracting extension of uploaded file
    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $temp = explode(".", $arrayimage["name"]);
    $extension = end($temp);

    //validating image
    if ((($arrayimage["type"] == "image/gif")
    || ($arrayimage["type"] == "image/jpeg")
    || ($arrayimage["type"] == "image/jpg")
    || ($arrayimage["type"] == "image/pjpeg")
    || ($arrayimage["type"] == "image/x-png")
    || ($arrayimage["type"] == "image/png"))

    //check image size

    && ($arrayimage["size"] < 20000000)

    //check iamge extension in above created extension array
    && in_array($extension, $allowedExts)) 
    {
        if ($arrayimage["error"] > 0) 
        {
            echo "Error: " . $arrayimage["error"] . "<br>";
        } 
        else 
        {
            echo "Upload: " . $arrayimage["name"] . "<br>";
            echo "Type: " . $arrayimage["type"] . "<br>";
            echo "Size: " . ($arrayimage["size"] / 1024) . " kB<br>";
            echo "Stored in: ".$arrayimage['tmp_name']."<br>";

            //check if file is exist in folder of not
            if (file_exists($dir."/".$arrayimage["name"])) 
            {
                echo $arrayimage['name'] . " already exists. ";
            } 
            else 
            {
                //extracting database fields and value
                foreach($fields as $key=>$val)
                {
                    $f[]=$key;
                    $v[]=$val;
                    $fi=implode(",",$f);
                    $value=implode("','",$v);
                }
                //dynamic sql for inserting data into any table
                $sql="INSERT INTO " . $table ."(".$fi.") VALUES ('".$value."')";
                //echo $sql;
                $imginsquery=mysql_query($sql);
                move_uploaded_file($arrayimage["tmp_name"],$dir."/".$arrayimage['name']);
                echo "<br> Stored in: " .$dir ."/ Folder <br>";

            }
        }
    } 
    //if file not match with extension
    else 
    {
        echo "Invalid file";
    }
}
//function imageUpload ends here
}

// здесь заканчивается класс imageFunctions

вы можете попробовать этот код для вставки нескольких изображений с его расширением, эта функция создана для проверки файлов изображений, вы можете заменить список расширений для perticular файлов в коде

Prateik Darji
источник
Привет всем, я использую файл ввода, чтобы прикрепить документы к автоматически сгенерированной электронной почте. Я могу прикрепить несколько документов за раз, однако я хотел бы прикрепить несколько документов из разных каталогов. В настоящее время, если я делаю это, мой текущий выбранный документ заменяется новым выбранным документом. Пожалуйста, как мне это сделать. Спасибо
Кунби
-1

частичный ответ: груша HTTP_UPLOAD может быть полезна http://pear.php.net/manual/en/package.http.http-upload.examples.php

есть полный пример для нескольких файлов

Дамко
источник
1
Вы можете использовать пакет PEAR, но эта задача довольно тривиальна, и если вам не нужны дополнительные функции, которые предоставляет пакет (интернационализированные сообщения об ошибках, проверка и т. Д.), Я бы порекомендовал использовать встроенные функции PHP. Но это только мое мнение. :)
MitMaro
Я согласен с вами, поэтому я написал «частичный ответ». Но я также делаю все возможное, чтобы повторно использовать код, и я часто работаю с грушей столько, сколько я могу (кодеры груш намного лучше меня :-D)
damko