Come posso selezionare e caricare più file con HTML e PHP, usando HTTP POST?


155

Ho esperienza nel fare questo con i caricamenti di singoli file utilizzando <input type="file">. Tuttavia, ho problemi a caricare più di uno alla volta.

Ad esempio, vorrei essere in grado di selezionare una serie di immagini, quindi caricarle sul server, tutto in una volta.

Sarebbe bello usare un controllo di input di un singolo file, se possibile.

Qualcuno sa come realizzare questo? Grazie!


2
Vuoi dire selezionare più di un file nella finestra di dialogo di selezione file o utilizzare più input di file?
MitMaro,

Ciao, è possibile caricare un file di archivio (zip, rar, tar, ...)?
sourcerebels,

Risposte:


196

Questo è possibile in HTML5 . Esempio (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>

Ecco come appare in Chrome dopo aver selezionato 2 elementi nella finestra di dialogo del file:

Chrome selezionare più file

Ed ecco come appare dopo aver fatto clic sul pulsante "Carica".

invio di più file a PHP

Questo è solo uno schizzo di una risposta pienamente funzionante. Consulta il Manuale di PHP: Gestione dei caricamenti di file per ulteriori informazioni sulla gestione corretta e sicura dei caricamenti di file in PHP.


8
supera la convalida w3c o dovrebbe essere multiple="multiple"?
vol7ron,

10
Credo che sia valido: thoughtresults.com/html5-boolean-attributes . Passa il validatore w3c se aggiungi <! Doctype html>.
Mark E. Haase,

2
sì, probabilmente convalida HTML, ma non riesce XHTML. Anche se mi piace ancora usare XHTML, penso che le persone consigliano di starne alla larga in questi giorni.
vol7ron,

11
Non ha funzionato senza l'aggiunta del nome della proprietà (ad es name="file[]".). Ho provato a modificare la risposta , ma è stata respinta.
Michel Ayres,

1
Grazie @MichelAyres, ho aggiornato la mia risposta. Quando ho scritto questo originale, ho affrontato solo la parte HTML del problema b / c c'erano altre risposte che spiegavano la parte PHP. Nel corso del tempo, questa è diventata una risposta popolare, quindi ora ho ampliato per coprire sia HTML che PHP.
Mark E. Haase,

94

Ci sono alcune cose che devi fare per creare un caricamento di più file, in realtà è piuttosto semplice. Non è necessario utilizzare Java, Ajax, Flash. Basta compilare un normale modulo di caricamento file a partire da:

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

Quindi la chiave del successo;

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

NON dimenticare quelle parentesi! Nel post_upload.php provare quanto segue:

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

Si noti che si ottiene un array con dati tmp_name, il che significa che è possibile accedere a ciascun file con una terza coppia di parentesi con l'esempio 'numero' del file:

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

Puoi usare php count () per contare il numero di file che è stato selezionato. Buona fortuna!


5
Grazie per il consiglio! mi ha fatto risparmiare così tanto tempo +1
BPm

Funziona molto bene ... ma ho problemi a caricare in questo modo in Internet Explorer (v8). Penso che IE non supporti il ​​caricamento in questo modo.
Tariq M Nasim,

4
Oppure puoi scorrere i file in foreach
sequenza

Nota, se usi una chiave nel tuo nome nel tuo html, ad es. Name = "file [3]", allora devi accedere al valore tramite $ _FILES ['file'] ['tmp_name'] [3], nel caso non è ovvio.
MyStream,

8

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

Il codice è stato troncato. Ecco cosa succede appena sopra: <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
Tuttavia, non ha funzionato in IE8, ma utilizza solo un browser reale.
Thaps

5

Se si desidera selezionare più file dalla finestra di dialogo del selettore file che viene visualizzata quando si seleziona Sfoglia, si è per lo più sfortunati. Dovrai usare un'applet Java o qualcosa di simile (penso che ce ne sia uno che usi un piccolo file flash, lo aggiornerò se lo trovo). Attualmente un singolo file consente solo la selezione di un singolo file.

Se stai parlando di utilizzare più input di file, non dovrebbe esserci molta differenza dall'usarne uno. Pubblica un po 'di codice e cercherò di aiutarti ulteriormente.


Aggiornamento: esiste un metodo per utilizzare un singolo pulsante "Sfoglia" che utilizza Flash. Non l'ho mai usato personalmente, ma ne ho letto abbastanza. Penso che sia il tuo colpo migliore.

http://swfupload.org/


1
Ho aggiunto il collegamento all'uploader multiplo basato su Flash.
MitMaro,

Ho usato swfupload fwiw - a volte è un po 'una seccatura ma non è poi così difficile iniziare a lavorare.
Meep3D,

@Barsoom è corretto. Le cose sono migliorate molto negli upload di più file negli ultimi due anni. : D
MitMaro,

4

nel primo dovresti creare una forma come questa:

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

è giusto . ora aggiungi questo codice sotto il codice del modulo o nella pagina che ti piace

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

è facile ... finisci


1

Se si utilizzano più campi di input, è possibile impostare name = "file []" (o qualsiasi altro nome). Ciò li inserirà in un array quando li carichi ( $_FILES['file'] = array ({file_array},{file_array]..))


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>

Utilizzando FOR Loop

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

    }               
  }    
?>

Utilizzando FOREACH Loop

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

    }               
  }
?>

0

ho creato una funzione php che viene utilizzata per caricare più immagini, questa funzione può caricare più immagini in una cartella specifica e può salvare i record nel database nel seguente codice $ arrayimage è l'array di immagini che viene inviato tramite il modulo note che non consentirà al caricamento di utilizzarne più, ma è necessario creare un campo di input diverso con lo stesso nome, in quanto è possibile impostare il campo di aggiunta dinamica del file unput al clic del pulsante.

$ dir è la directory in cui si desidera salvare l'immagine $ fields è il nome del campo che si desidera memorizzare nel database

il campo del database deve essere nell'esempio del formato dell'array se si dispone di un archivio del database e il nome dei campi come ID, nome, indirizzo, è necessario pubblicare dati come

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

e quindi passare quel campo nella funzione $ campi

$ table è il nome della tabella in cui si desidera archiviare i dati.

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
}

// La classe imageFunctions termina qui

puoi provare questo codice per inserire più immagini con la sua estensione, questa funzione è stata creata per controllare i file di immagine, puoi sostituire l'elenco di estensioni per i file perticolari nel codice


Ciao a tutti, utilizzo l'input del file per allegare documenti a un'e-mail generata automaticamente. Sono in grado di allegare più documenti in una volta, tuttavia, vorrei allegare più documenti da directory diverse. Al momento, se lo faccio, il mio documento attualmente selezionato viene sostituito dal nuovo documento che seleziono. Per favore, come posso procedere. Grazie
Kunbi,

-1

risposta parziale: HTTP_UPLOAD pera può essere utile http://pear.php.net/manual/en/package.http.http-upload.examples.php

c'è un esempio completo per più file


1
Puoi usare il pacchetto PEAR ma questa attività è piuttosto banale e, a meno che tu non abbia bisogno delle funzionalità extra che il pacchetto fornisce (messaggi di errore internazionalizzati, validazione, ecc ...), consiglierei di usare le funzioni native di PHP. Ma questa è solo la mia opinione. :)
MitMaro,

Sono d'accordo con te, ecco perché ho scritto "risposta parziale". Ma faccio anche del mio meglio per riutilizzare il codice e spesso lavoro il più possibile con la pera (i programmatori di pere sono molto più migliori di me
MrGreen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.