Enviando múltiplos arquivos

Múltiplos arquivos podem ser enviados usando diferentes nomes (name) para entradas (input).

Também é possível carregar vários arquivos simultaneamente e ter a informação automaticamente organizada em arrays. Para isso, é necessário usar a mesma sintaxe das arrays submetidas pelo formulário HTML que você usa para múltiplos selects e checkboxes:

Exemplo #1 Carregando múltiplos arquivos

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Envie esses arquivos:<br />
  <input name="userfile[]" type="file" /><br />
  <input name="userfile[]" type="file" /><br />
  <input type="submit" value="Enviar arquivos" />
</form>

Quando o formulário acima é submetido, os arrays $_FILES['userfile'], $_FILES['userfile']['name'], e $_FILES['userfile']['size'] serão inicializados.

Por exemplo, suponha os nomes dos arquivos /home/test/review.html e /home/test/xwp.out. Neste caso, $_FILES['userfile']['name'][0] deve conter o valor review.html, e $_FILES['userfile']['name'][1] deve conter o valor xwp.out. Similarmente, $_FILES['userfile']['size'][0] deve conter o tamanho do arquivo review.html, e assim por diante.

$_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0], e $_FILES['userfile']['type'][0] também são definidas.

Aviso

O parâmetro max_file_uploads atua como um limite no número de arquivos que podem ser enviados em uma única requisição. Você precisa ter certeza que seu formulário não tentará enviar mais arquivos que o limite definido.

Exemplo #2 Carregando um diretório inteiro

Nos campos de carregamento de arquivos HTML, é possível carregar um diretório inteiro com o atributo webkitdirectory. Esse recurso é suportado na maioria dos navegadores modernos.

Com a informação full_path, é possível armazenar os caminhos relativos, ou reconstruir o mesmo diretório no servidor.

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Enviar este diretório:<br />
  <input name="userfile[]" type="file" webkitdirectory multiple />
  <input type="submit" value="Enviar arquivos" />
</form>
Aviso

O atributo webkitdirectory não é padronizado e não está no roteiro de padronização. Não utilize-o em sites em produção voltados para a Web: ele não funcionará para todos os usuários. Também podem haver grandes incompatibilidades entre implementações e o comportamento pode mudar no futuro.

O PHP analisa apenas a informação de caminho relativo enviada pelo navegador/user-agent, e passa essa informação para o array $_FILES. Não há garantia de que os valores no array full_path contenham uma estrutura de diretórios real, e a aplicação PHP não deve confiar nesta informação.

adicione uma nota

Notas Enviadas por Usuários (em inglês) 8 notes

up
357
phpuser at gmail dot com
20 years ago
When uploading multiple files, the $_FILES variable is created in the form:Array(    [name] => Array        (            [0] => foo.txt            [1] => bar.txt        )    [type] => Array        (            [0] => text/plain            [1] => text/plain        )    [tmp_name] => Array        (            [0] => /tmp/phpYzdqkD            [1] => /tmp/phpeEwEWG        )    [error] => Array        (            [0] => 0            [1] => 0        )    [size] => Array        (            [0] => 123            [1] => 456        ))I found it made for a little cleaner code if I had the uploaded files array in the formArray(    [0] => Array        (            [name] => foo.txt            [type] => text/plain            [tmp_name] => /tmp/phpYzdqkD            [error] => 0            [size] => 123        )    [1] => Array        (            [name] => bar.txt            [type] => text/plain            [tmp_name] => /tmp/phpeEwEWG            [error] => 0            [size] => 456        ))I wrote a quick function that would convert the $_FILES array to the cleaner (IMHO) array.<?phpfunction reArrayFiles(&$file_post) {    $file_ary = array();    $file_count = count($file_post['name']);    $file_keys = array_keys($file_post);    for ($i=0; $i<$file_count; $i++) {        foreach ($file_keys as $key) {            $file_ary[$i][$key] = $file_post[$key][$i];        }    }    return $file_ary;}?>Now I can do the following:<?phpif ($_FILES['upload']) {    $file_ary = reArrayFiles($_FILES['ufile']);    foreach ($file_ary as $file) {        print 'File Name: ' . $file['name'];        print 'File Type: ' . $file['type'];        print 'File Size: ' . $file['size'];    }}?>
up
21
i.g.e.o@ya (dot) ru
5 years ago
A bit update to 14 year ago note from "phpuser at gmail dot com".That update converts to a really more friendly array form incoming _POST info for uploaded files. And that variants works identical for non-multiple uploads and multiple uploads:<?php//Функция переформатирует массив поданных POST'ом файловfunction reArrayFiles(&$file_post){    $isMulti    = is_array($file_post['name']);    $file_count    = $isMulti?count($file_post['name']):1;    $file_keys    = array_keys($file_post);    $file_ary    = [];    //Итоговый массив    for($i=0; $i<$file_count; $i++)        foreach($file_keys as $key)            if($isMulti)                $file_ary[$i][$key] = $file_post[$key][$i];            else                $file_ary[$i][$key]    = $file_post[$key];    return $file_ary;}?>
up
51
wizzard351 at yahoo dot com
11 years ago
This is also needed for <input type=file multiple> elements.So, if you have an input element like this:<input type="file" multiple="multiple" name="foobar" />This should be written as<input type="file" multiple="multiple" name="foobar[]" />else you'll only be able to get one of the files.
up
13
Corey Ballou
15 years ago
Here is a function to fix the indices of a multi-dimensional for easier parsing when dealing with file uploads.  It takes a single $_FILES field array as a parameter and separates each individual uploaded file by numeric key.  This allows for iterating like:<?phpfixFilesArray($_FILES['array_of_files']);foreach ($_FILES['array_of_files'] as $position => $file) {    // should output array with indices name, type, tmp_name, error, size    var_dump($file);}?>Here's the code:<?php/** * Fixes the odd indexing of multiple file uploads from the format: * * $_FILES['field']['key']['index'] * * To the more standard and appropriate: * * $_FILES['field']['index']['key'] * * @param array $files * @author Corey Ballou * @link http://www.jqueryin.com */function fixFilesArray(&$files){    $names = array( 'name' => 1, 'type' => 1, 'tmp_name' => 1, 'error' => 1, 'size' => 1);    foreach ($files as $key => $part) {        // only deal with valid keys and multiple files        $key = (string) $key;        if (isset($names[$key]) && is_array($part)) {            foreach ($part as $position => $value) {                $files[$position][$key] = $value;            }            // remove old key reference            unset($files[$key]);        }    }}?>
up
14
timspeelman at live dot nl
13 years ago
The cleanest way to rearrange the $_FILES<?phpfunction rearrange( $arr ){    foreach( $arr as $key => $all ){        foreach( $all as $i => $val ){            $new[$i][$key] = $val;            }        }    return $new;}?>
up
6
lookphp at gmail dot com
9 years ago
This is a very simple example:Part I : HTML<!doctype html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <form action="upload.php" method="post" multipart="" enctype="multipart/form-data">        <input type="file" name="img[]" multiple>        <input type="submit">    </form></body></html>Part II : PHP<?phpecho '<pre>';$img = $_FILES['img'];if(!empty($img)){    $img_desc = reArrayFiles($img);    print_r($img_desc);        foreach($img_desc as $val)    {        $newname = date('YmdHis',time()).mt_rand().'.jpg';        move_uploaded_file($val['tmp_name'],'./uploads/'.$newname);    }}function reArrayFiles($file){    $file_ary = array();    $file_count = count($file['name']);    $file_key = array_keys($file);        for($i=0;$i<$file_count;$i++)    {        foreach($file_key as $val)        {            $file_ary[$i][$val] = $file[$val][$i];        }    }    return $file_ary;}
up
0
steam dot bakyt2 at gmail dot com
1 year ago
Just combine temporary path with the filename which will result an array like:array(2) {  ["/tmp/phpAYCvcc"]=> string(10) "file1.jpg"  ["/tmp/phpCDg79o"]=> string(10) "file2.jpg"}The code:$files = array_combine(     $_FILES['receipt']['tmp_name'],      $_FILES['receipt']['name']);foreach ($files as $key => $value) {    // save your files locally}
up
-1
sabryabdelmohsen at gmail dot com
4 years ago
function reArrayImages($file_post) {    $file_ary = [];    $file_keys = array_keys($file_post);    foreach ($file_post as $key => $value) {      foreach ($value as $key2 => $value2) {        $file_ary[$key2][$key] = $value2;      }    }    return $file_ary;}
To Top