Wie kann ich mithilfe von HTTP POST mehrere Dateien mit HTML und PHP auswählen und hochladen?

154

Ich habe Erfahrung damit, einzelne Dateien hochzuladen <input type="file">. Ich habe jedoch Probleme, mehrere gleichzeitig hochzuladen.

Zum Beispiel möchte ich in der Lage sein, eine Reihe von Bildern auszuwählen und sie dann gleichzeitig auf den Server hochzuladen.

Wenn möglich, wäre es großartig, ein einzelnes Dateieingabesteuerelement zu verwenden.

Weiß jemand, wie man das erreicht? Vielen Dank!

Stalepretzel
quelle
2
Meinen Sie damit, dass Sie im Dateiauswahldialog mehr als eine Datei auswählen oder mehrere Dateieingaben verwenden?
MitMaro
Hallo, können Sie eine Archivdatei hochladen (zip, rar, tar, ...)?
Sourcerebels

Antworten:

195

Dies ist in HTML5 möglich . Beispiel (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>

So sieht es in Chrome aus, nachdem Sie zwei Elemente im Dateidialog ausgewählt haben:

Chrome Multiple File Select

Und so sieht es aus, nachdem Sie auf die Schaltfläche "Hochladen" geklickt haben.

Senden mehrerer Dateien an PHP

Dies ist nur eine Skizze einer voll funktionsfähigen Antwort. Weitere Informationen zur ordnungsgemäßen und sicheren Behandlung von Datei-Uploads in PHP finden Sie im PHP-Handbuch: Behandeln von Datei-Uploads.

Mark E. Haase
quelle
8
Besteht es die w3c-Validierung oder sollte es so sein multiple="multiple"?
Vol7ron
10
Ich glaube, es ist gültig: obwohltresults.com/html5-boolean-attributes . Es besteht den w3c-Validator, wenn Sie <! Doctype html> hinzufügen.
Mark E. Haase
2
Ja, es validiert wahrscheinlich HTML, schlägt aber XHTML fehl. Obwohl ich XHTML immer noch gerne benutze, denke ich, dass die Leute heutzutage raten, sich davon fernzuhalten.
Vol7ron
11
Es hat nicht funktioniert , ohne dass die Eigenschaft Hinzufügen von Namen (zB name="file[]"). Ich habe versucht , die Antwort zu bearbeiten , aber sie wurde abgelehnt.
Michel Ayres
1
Danke @MichelAyres, ich habe meine Antwort aktualisiert. Als ich dies ursprünglich schrieb, ging ich nur auf den HTML-Teil des Problems ein. Es gab andere Antworten, die den PHP-Teil erklärten. Im Laufe der Zeit wurde dies eine beliebte Antwort, daher habe ich mich jetzt auf HTML und PHP ausgeweitet.
Mark E. Haase
94

Es gibt ein paar Dinge, die Sie tun müssen, um einen Upload mit mehreren Dateien zu erstellen. Sie müssen nicht Java, Ajax, Flash verwenden. Erstellen Sie einfach ein normales Formular zum Hochladen von Dateien, beginnend mit:

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

Dann der Schlüssel zum Erfolg;

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

Vergessen Sie diese Klammern NICHT! Versuchen Sie in der post_upload.php Folgendes:

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

Beachten Sie, dass Sie ein Array mit tmp_name-Daten erhalten. Dies bedeutet, dass Sie auf jede Datei mit einem dritten Klammerpaar mit dem Beispiel 'number' zugreifen können:

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

Sie können php count () verwenden, um die Anzahl der ausgewählten Dateien zu zählen. Viel Glück widdit!

Epoxys
quelle
5
Danke für den Tipp! es hat mir so viel Zeit gespart +1
BPm
Es funktioniert sehr gut ... aber ich habe Probleme beim Hochladen auf diese Weise in Internet Explorer (v8). Ich denke, IE unterstützt das Hochladen auf diese Weise nicht.
Tariq M Nasim
4
Oder Sie können die Dateien mit einer foreachAnweisung durchlaufen , ohne die Anzahl der hochgeladenen Dateien kennen zu müssen ...
ygesher
Hinweis: Wenn Sie in Ihrem HTML-Code einen Schlüssel in Ihrem Namen verwenden, z. B. name = "file [3]", müssen Sie für den Fall über $ _FILES ['file'] ['tmp_name'] [3] auf den Wert zugreifen das ist nicht offensichtlich.
MyStream
8

Vollständige Lösung in 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
quelle
Der Code wurde abgeschnitten. Hier ist, was direkt darüber kommt: <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
In IE8 hat es zwar nicht funktioniert, aber dann einfach einen richtigen Browser verwenden.
Thaps
5

Wenn Sie mehrere Dateien aus dem Dateiauswahldialog auswählen möchten, der angezeigt wird, wenn Sie Durchsuchen auswählen, haben Sie größtenteils kein Glück. Sie müssen ein Java-Applet oder ähnliches verwenden (ich glaube, es gibt eines, das eine kleine Flash-Datei verwendet, die ich aktualisieren werde, wenn ich sie finde). Derzeit ermöglicht eine einzelne Dateieingabe nur die Auswahl einer einzelnen Datei.

Wenn Sie über die Verwendung mehrerer Dateieingaben sprechen, sollte es keinen großen Unterschied zur Verwendung einer geben. Poste einen Code und ich werde versuchen, weiter zu helfen.


Update: Es gibt eine Methode, um eine einzelne Schaltfläche zum Durchsuchen zu verwenden, die Flash verwendet. Ich habe das nie persönlich benutzt, aber ich habe eine ganze Menge darüber gelesen. Ich denke, es ist dein bester Schuss.

http://swfupload.org/

MitMaro
quelle
1
Ich habe den Link zum Flash-basierten Mehrfach-Uploader hinzugefügt.
MitMaro
Ich habe swfupload fwiw verwendet - es ist manchmal ein bisschen schmerzhaft, aber es ist nicht wirklich so schwer, an die Arbeit zu kommen.
Meep3D
@Barsoom ist korrekt. Bei den mehreren Datei-Uploads in den letzten Jahren ist es viel besser geworden. : D
MitMaro
4

in der ersten sollten Sie Form wie folgt machen:

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

das ist richtig . Fügen Sie diesen Code nun unter Ihrem Formularcode oder auf einer beliebigen Seite hinzu

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

es ist einfach ... fertig

Pooya Laryan
quelle
1

Wenn Sie mehrere Eingabefelder verwenden, können Sie name = "file []" (oder einen anderen Namen) festlegen. Dadurch werden sie beim Hochladen in ein Array eingefügt ( $_FILES['file'] = array ({file_array},{file_array]..))

Torandi
quelle
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-Schleife verwenden

<?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}.";                               
      }                 

    }               
  }    
?>

Verwenden der FOREACH-Schleife

<?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}.";                               
      }                 

    }               
  }
?>
Anteliebe
quelle
0

Ich habe eine PHP-Funktion erstellt, die zum Hochladen mehrerer Bilder verwendet wird. Diese Funktion kann mehrere Bilder in einem bestimmten Ordner hochladen und die Datensätze im folgenden Code in der Datenbank speichern. $ arrayimage ist das Array von Bildern, das über die Formularnotiz gesendet wird Damit der Upload nicht mehrere verwenden kann, müssen Sie jedoch ein anderes Eingabefeld mit demselben Namen erstellen und das dynamische Hinzufügen eines Felds für die Eingabe von Dateien beim Klicken auf die Schaltfläche festlegen.

$ dir ist das Verzeichnis, in dem Sie das Bild speichern möchten. $ fields ist der Name des Feldes, das Sie in der Datenbank speichern möchten

Das Datenbankfeld muss in einem Array-Format vorliegen. Wenn Sie einen Datenbank-Imagestore und einen Feldnamen wie ID, Name, Adresse haben, müssen Sie Daten wie veröffentlichen

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

und übergeben Sie dieses Feld dann an die Funktion $ fields

$ table ist der Name der Tabelle, in der Sie die Daten speichern möchten.

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
}

// Die imageFunctions-Klasse endet hier

Sie können diesen Code zum Einfügen mehrerer Bilder mit seiner Erweiterung ausprobieren. Diese Funktion wurde zum Überprüfen von Bilddateien erstellt. Sie können die Erweiterungsliste für bestimmte Dateien im Code ersetzen

Prateik Darji
quelle
Hallo zusammen, ich verwende die Dateieingabe, um Dokumente an eine automatisch generierte E-Mail anzuhängen. Ich kann mehrere Dokumente gleichzeitig anhängen, möchte jedoch mehrere Dokumente aus verschiedenen Verzeichnissen anhängen. Wenn ich dies tue, wird mein aktuell ausgewähltes Dokument derzeit durch das neue Dokument ersetzt, das ich auswähle. Bitte wie gehe ich vor? Danke
Kunbi
-1

Teilantwort: Birne HTTP_UPLOAD kann nützlich sein. http://pear.php.net/manual/en/package.http.http-upload.examples.php

Es gibt ein vollständiges Beispiel für mehrere Dateien

Damko
quelle
1
Sie können das PEAR-Paket verwenden, aber diese Aufgabe ist ziemlich trivial. Sofern Sie nicht die zusätzlichen Funktionen benötigen, die das Paket bietet (internationalisierte Fehlermeldungen, Validierung usw.), würde ich die Verwendung der nativen PHP-Funktionen empfehlen. Das ist aber nur meine Meinung. :)
MitMaro
Ich stimme Ihnen zu, deshalb habe ich "Teilantwort" geschrieben. Aber ich gebe auch mein Bestes, um Code wiederzuverwenden, und ich arbeite oft so viel wie möglich mit Birnen (Birnencodierer sind viel besser als ich :-D)
damko