Jak mogę wybrać i przesłać wiele plików z HTML i PHP, używając HTTP POST?

155

Mam doświadczenie w robieniu tego z przesyłaniem pojedynczych plików przy użyciu <input type="file">. Jednak mam problemy z przesyłaniem więcej niż jednego na raz.

Na przykład chciałbym móc wybrać serię obrazów, a następnie przesłać je na serwer, wszystkie naraz.

Byłoby wspaniale, jeśli to możliwe, użyć kontrolki wejścia pojedynczego pliku.

Czy ktoś wie, jak to osiągnąć? Dzięki!

stalepretzel
źródło
2
Czy masz na myśli wybranie więcej niż jednego pliku w oknie dialogowym wyboru pliku, czy używanie wielu plików wejściowych?
MitMaro,
Cześć, Czy możesz załadować plik archiwum (zip, rar, tar, ...)?
sourcerebels

Odpowiedzi:

196

Jest to możliwe w HTML5 . Przykład (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>

Oto, jak to wygląda w przeglądarce Chrome po wybraniu 2 elementów w oknie dialogowym plików:

chrome wybór wielu plików

A tak to wygląda po kliknięciu przycisku „Prześlij”.

przesyłanie wielu plików do PHP

To tylko szkic w pełni działającej odpowiedzi. Zobacz Podręcznik PHP: Obsługa przesyłania plików, aby uzyskać więcej informacji na temat prawidłowej, bezpiecznej obsługi przesyłania plików w PHP.

Mark E. Haase
źródło
8
czy przechodzi walidację w3c, czy powinno być multiple="multiple"?
vol7ron
10
Uważam, że to poprawne: thinkresults.com/html5-boolean-attributes . Przekazuje walidator w3c, jeśli dodasz <! Doctype html>.
Mark E. Haase,
2
tak, prawdopodobnie sprawdza poprawność HTML, ale zawodzi XHTML. Mimo że nadal lubię używać XHTML, myślę, że obecnie ludzie radzą trzymać się od niego z daleka.
vol7ron
11
Nie działało bez dodania nazwy właściwości (np name="file[]".). Próbowałem edytować odpowiedź , ale została odrzucona.
Michel Ayres
1
Dzięki @MichelAyres, zaktualizowałem odpowiedź. Kiedy pisałem to pierwotnie, odniosłem się tylko do HTML problemu, b / c były inne odpowiedzi, które wyjaśniały część PHP. Z biegiem czasu ta odpowiedź stała się popularna, więc teraz rozszerzyłem ją, aby objąć zarówno HTML, jak i PHP.
Mark E. Haase
94

Jest kilka rzeczy, które musisz zrobić, aby utworzyć przesyłanie wielu plików, w rzeczywistości jest to dość podstawowe. Nie musisz używać Java, Ajax, Flash. Po prostu zbuduj normalny formularz przesyłania plików, zaczynając od:

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

Następnie klucz do sukcesu;

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

NIE zapomnij o tych nawiasach! W post_upload.php spróbuj wykonać następujące czynności:

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

Zauważ, że otrzymujesz tablicę z danymi tmp_name, co oznacza, że ​​możesz uzyskać dostęp do każdego pliku za pomocą trzeciej pary nawiasów z przykładem pliku „numer”:

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

Możesz użyć php count (), aby policzyć liczbę wybranych plików. Goodluck widdit!

Epoksydy
źródło
5
Dzięki za wskazówkę! zaoszczędziło mi to tyle czasu +1
BPm
Działa bardzo dobrze ... ale mam problem z przesyłaniem w ten sposób w Internet Explorerze (v8). Myślę, że IE nie obsługuje przesyłania w ten sposób.
Tariq M Nasim
4
Lub możesz przeglądać pliki z foreachoświadczeniem, bez konieczności znajomości liczby przesłanych plików ...
ygesher
Uwaga, jeśli używasz klucza w swoim imieniu w swoim html, np. Name = "file [3]", musisz uzyskać dostęp do wartości poprzez $ _FILES ['file'] ['tmp_name'] [3], w przypadku to nie jest oczywiste.
MyStream
8

Pełne rozwiązanie w przeglądarce 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
źródło
Kod ucięty. Oto, co pojawia się tuż nad tym: <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>
Od
3
Nie działało to jednak w IE8, ale po prostu użyj prawdziwej przeglądarki.
Od
5

Jeśli chcesz wybrać wiele plików z okna dialogowego wyboru plików, które wyświetla się po wybraniu przeglądania, masz przeważnie pecha. Będziesz musiał użyć apletu Java lub czegoś podobnego (myślę, że jest taki, który używa małego pliku flash, zaktualizuję, jeśli go znajdę). Obecnie pojedynczy plik wejściowy pozwala na wybór tylko jednego pliku.

Jeśli mówisz o korzystaniu z wielu plików wejściowych, nie powinno być dużej różnicy w stosunku do jednego. Napisz kod, a ja postaram się pomóc dalej.


Aktualizacja: jest jedna metoda korzystania z pojedynczego przycisku „przeglądaj”, który korzysta z technologii Flash. Nigdy nie korzystałem z tego osobiście, ale sporo o tym czytałem. Myślę, że to twoja najlepsza szansa.

http://swfupload.org/

MitMaro
źródło
1
Dodałem łącze do programu do przesyłania wielu plików w formacie flash.
MitMaro
Użyłem swfupload fwiw - czasami jest to trochę uciążliwe, ale naprawdę nie jest tak trudno pracować.
Meep3D
@Barsoom ma rację. W ciągu ostatnich kilku lat sytuacja się poprawiła w przypadku przesyłania wielu plików. : D
MitMaro
4

w pierwszej kolejności należy wykonać następującą postać:

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

to prawda. teraz dodaj ten kod pod kodem formularza lub na dowolnej stronie, którą chcesz

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

to łatwe ... wykończenie

pooya laryan
źródło
1

Jeśli używasz wielu pól wejściowych, możesz ustawić nazwę = "plik []" (lub dowolną inną nazwę). Spowoduje to umieszczenie ich w tablicy podczas ich przesyłania ( $_FILES['file'] = array ({file_array},{file_array]..))

Torandi
źródło
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>

Korzystanie z pętli 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}.";                               
      }                 

    }               
  }    
?>

Korzystanie z pętli 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
źródło
0

stworzyłem funkcję php, która służy do przesyłania wielu obrazów, ta funkcja może przesyłać wiele obrazów w określonym folderze, a także może zapisywać rekordy w bazie danych w następującym kodzie $ arrayimage to tablica obrazów wysyłana za pośrednictwem notatki formularza że nie pozwoli to na przesyłanie wielu plików, ale musisz utworzyć inne pole wejściowe o tej samej nazwie, ponieważ możesz ustawić dynamiczne dodawanie pola usuwania pliku po kliknięciu przycisku.

$ dir to katalog w którym chcesz zapisać obraz $ pola to nazwa pola które chcesz przechowywać w bazie danych

pole bazy danych musi być w formacie tablicowym przykład jeśli masz bazę danych i nazwę pola, taką jak id, nazwa, adres, musisz opublikować dane takie jak

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

a następnie przekaż to pole do pól funkcji $

$ table to nazwa tabeli, w której chcesz przechowywać dane.

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
}

// Klasa imageFunctions kończy się tutaj

możesz wypróbować ten kod do wstawiania wielu obrazów z jego rozszerzeniem ta funkcja jest stworzona do sprawdzania plików graficznych możesz zamienić listę rozszerzeń dla poszczególnych plików w kodzie

Prateik Darji
źródło
Cześć wszystkim, używam pliku wejściowego do załączania dokumentów do automatycznie generowanej wiadomości e-mail. Jestem w stanie załączyć wiele dokumentów na raz, jednak chciałbym załączyć wiele dokumentów z innego katalogu. Obecnie, jeśli to zrobię, mój aktualnie wybrany dokument jest zastępowany przez nowy wybrany przeze mnie dokument. Proszę, jak mam się do tego zabrać. Dzięki
Kunbi
-1

odpowiedź częściowa: gruszka HTTP_UPLOAD może być przydatna http://pear.php.net/manual/en/package.http.http-upload.examples.php

jest pełny przykład dla wielu plików

damko
źródło
1
Możesz użyć pakietu PEAR, ale to zadanie jest dość trywialne i jeśli nie potrzebujesz dodatkowych funkcji, które zapewnia pakiet (zinternacjonalizowane komunikaty o błędach, walidacja itp.), Polecam używanie natywnych funkcji PHP. Ale to tylko moja opinia. :)
MitMaro
Zgadzam się z Tobą, dlatego napisałem „odpowiedź częściową”. Ale robię też co w mojej mocy, aby ponownie wykorzystać kod i często pracuję tyle, ile mogę z gruszką (kodery gruszkowe są znacznie lepsze ode mnie :-D)
cholera.