Caricamento di più file

È possibile inviare più file contemporanemante utilizzando differenti attributi name i per input.

E' possibile caricare più file contemporaneamente e avere le informazioni organizzate automaticamente in array. Per questo è necessario utilizzare la medesima sintassi di invio di array da form HTML che è utilizzata con select e checkbox multipli:

Example #1 Caricamento di più file

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Send these files:<br />
  <input name="userfile[]" type="file" /><br />
  <input name="userfile[]" type="file" /><br />
  <input type="submit" value="Send files" />
</form>

Quando la form è inviata, gli array $_FILES['userfile'], $_FILES['userfile']['name'], e $_FILES['userfile']['size'] saranno inizializzati (come sarà valorizzato $HTTP_POST_FILES per le versioni di PHP precedenti la 4.1.0). Quando il parametro register_globals è impostato a on saranno presenti anche le variabili globali. Ognuno di questi è un array indicizzato numericamente con i valori relativi ai diversi file caricati.

Per esempio, si supponga che i nomi di file /home/test/review.html e /home/test/xwp.out siano inviati. In questo caso, $_FILES['userfile']['name'][0] conterrebbe il valore review.html, e $_FILES['userfile']['name'][1] conterrebbe il valore xwp.out. Analogamente, $_FILES['userfile']['size'][0] conterrebbe la dimensione di review.html, e così via.

$_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0], e $_FILES['userfile']['type'][0] sono ugualmente impostati.

Avviso

Da PHP 5.2.12, il parametro di configurazione max_file_uploads limita il numero di file che possono essere caricati durante una richiesta. Occorre assicurarsi che il form non cerchi di caricare più file di questo limite.

add a note add a note

User Contributed Notes 10 notes

up
82
phpuser at gmail dot com
9 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 form

Array
(
    [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.

<?php

function 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:

<?php

if ($_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
12
wizzard351 at yahoo dot com
10 months 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
10
Corey Ballou
4 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:

<?php
fixFilesArray
($_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
11
timspeelman at live dot nl
3 years ago
The cleanest way to rearrange the $_FILES

<?php
function rearrange( $arr ){
    foreach(
$arr as $key => $all ){
        foreach(
$all as $i => $val ){
           
$new[$i][$key] = $val;   
        }   
    }
    return
$new;
}
?>
up
3
javad dot geek at gmail dot com
9 months ago
$countarray = count($_FILES['uploadfile']['name']);
                $newarray = array();
                for($i=0;$i<$countarray;$i++){
                    $newarray[$i]['name']=$_FILES['uploadfile']['name'][$i];
                    $newarray[$i]['type']=$_FILES['uploadfile']['type'][$i];
                    $newarray[$i]['tmp_name']=$_FILES['uploadfile']['tmp_name'][$i];
                    $newarray[$i]['error']=$_FILES['uploadfile']['error'][$i];
                    $newarray[$i]['size']=$_FILES['uploadfile']['size'][$i];
                }
up
3
jess at semlabs dot co dot uk
5 years ago
If you try and upload files with multi-dimensional names like this:

<input type="file" name="submission[screenshot]" />
<input type="file" name="other[dem][][img][]" />

You will get an unexpected format like this:

<?php
array(
   
'submission' => array
        (
           
'name' => array( 'screenshot' => 'monster_wallpaper.jpg' ),
           
'type' => array( 'screenshot' => 'image/jpeg' ),
           
'tmp_name' => array( 'screenshot' => '/tmp/php48lX2Y' ),
           
'error' => array( 'screenshot' => 0 ),
           
'size' => array( 'screenshot' => 223262 ),
        ),
....
?>

You can use the following function to re-format the array recursively in the usual format:

<?php
function format_files_array( $files, $name = null, &$new = false, $path = false ){
   
$names = array( 'name' => 'name', 'type' => 'type', 'tmp_name' => 'tmp_name', 'error' => 'error', 'size' => 'size' );
   
    foreach(
$files as $key => &$part )
    {
       
$key = ( string ) $key;
        if(
in_array( $key, $names ) )
           
$name = $key;
        if( !
in_array( $key, $names ) )
           
$path[] = $key;
        if(
is_array( $part ) )
           
$part = format_files_array( $part, $name, $new, $path );
        elseif( !
is_array( $part ) )
        {
           
$current =& $new;
            foreach(
$path as $p )
               
$current =& $current[$p];
           
$current[$name] = $part;
            unset(
$path );
           
$name = null;
        }
    }
   
    return
$new;
}
?>
up
1
contato at dgmike dot com dot br
3 years ago
I prefer something like this!

<?php
public function arrayImages ( &$file_post )
{
    if( empty(
$file_post ) ) {
        return
$file_post;
    }
    if(
'array'!==gettype($file_post['name']) ) {
        return
$file_post;
    }
   
$keys = array_keys($file_post['name']);
   
$file_array = array();
    foreach (
$keys as $key) {
       foreach (
$file_post as $res=>$item) {
          
$file_array[$key][$res] = $item[$key];
       }
   }
   return
$file_array;
}
?>
up
1
hotmail.com[at]notdefix
7 years ago
With multiple file uploads

post_max_size: the total amount of data posted by the client (all files, and all other form field)

upload_max_filesize: the maximum size of 1 single file. (just like <input type="hidden" name="MAX_FILE_SIZE" value="..."/>)

so, with the directives:
post_max_size 25M
upload_max_filesize 2M

you can send 12 files of up to 2 MB and use up to 1 MB for your additional form-values.

As long as you read only a single copy of 1 file into memory, the memory_limit directive can be held reasonable small as well.
up
-8
ohcnim at hotmail dot com
1 year ago
by simply naming differently each file input you'll get easily accesible arrays from $_FILES, in the form $_FILES['input_name']['file_attribute'].  For example:

$_FILES['input_name1']['name']...['input_name1']['size']
$_FILES['input_name2']['name']...['input_name2']['size']
$_FILES['input_nameX']['name']...['input_nameX']['size']
up
-12
christiaan at baartse dot nl
4 years ago
After trying dozens of ways that are supposed to fix the wonkyness of the $_FILES array I didn't find any that could work with a input name like: userfile[christiaan][][][is][gaaf][]

So I came up with this class
<?php
/**
* A class that takes the pain out of the $_FILES array
* @author Christiaan Baartse <christiaan@baartse.nl>
*/
class UploadedFiles extends ArrayObject
{
    public function
current() {
        return
$this->_normalize(parent::current());
    }

    public function
offsetGet($offset) {
        return
$this->_normalize(parent::offsetGet($offset));
    }

    protected function
_normalize($entry) {
        if(isset(
$entry['name']) && is_array($entry['name'])) {
           
$files = array();
            foreach(
$entry['name'] as $k => $name) {
               
$files[$k] = array(
                   
'name' => $name,
                   
'tmp_name' => $entry['tmp_name'][$k],
                   
'size' => $entry['size'][$k],
                   
'type' => $entry['type'][$k],
                   
'error' => $entry['error'][$k]
                );
            }
            return new
self($files);
        }
        return
$entry;
    }
}
?>

This allows you to access a file uploaded using the following inputtype
<input type="file" name="userfile[christiaan][][][is][gaaf][]" />
like
<?php
$files
= new UploadedFiles($_FILES);
var_dump($files['userfile']['christiaan'][0][0]['is']['gaaf'][0]);
// or
foreach($files['userfile']['christiaan'][0][0]['is']['gaaf'] as $file) {
   
var_dump($file);
}
?>
To Top