PHP 5.6.18 is available

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 13 notes

up
159
phpuser at gmail dot com
10 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
30
wizzard351 at yahoo dot com
2 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
2
swayalex at gmail dot com
3 months ago
Recursive solution for complex situations (supports any nested arrays including indexed arrays)

function getFixedFilesArray() {
    $walker = function ($arr, $fileInfokey, callable $walker) {
        $ret = array();
        foreach ($arr as $k => $v) {
            if (is_array($v)) {
                $ret[$k] = $walker($v, $fileInfokey, $walker);
            } else {
                $ret[$k][$fileInfokey] = $v;
            }
        }
        return $ret;
    };

    $files = array();
    foreach ($_FILES as $name => $values) {
        // init for array_merge
        if (!isset($files[$name])) {
            $files[$name] = array();
        }
        if (!is_array($values['error'])) {
            // normal syntax
            $files[$name] = $values;
        } else {
            // html array feature
            foreach ($values as $fileInfoKey => $subArray) {
                $files[$name] = array_replace_recursive($files[$name], $walker($subArray, $fileInfoKey, $walker));
            }
        }
    }

    return $files;
}
up
12
Corey Ballou
5 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
12
timspeelman at live dot nl
4 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
jess at semlabs dot co dot uk
6 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
0
Eric
2 months ago
This is just a modification of the code which is the top note by "phpuser" here. His/her version requires that the $file_post array passed in to the function was created by a form submitted with the multiple attribute set. With multiple set in the html input tag, $_FILES["fileInputName"]["name"] is an array no matter if only one file is sent or multiple. But when <input type="file"> is used without the multiple attribute then $_FILES["fileInputName"]["name"] is not an array, it contains the the string with the filename. To use this neat function with or without multiple set and to get back an array which you can "foreach" over in either case, use this modification:

function reArrayFiles(&$file_post)
{
    $file_ary = array();
    $multiple = is_array($file_post['name']);

    $file_count = $multiple ? count($file_post['name']) : 1;
    $file_keys = array_keys($file_post);

    for ($i=0; $i<$file_count; $i++)
    {
        foreach ($file_keys as $key)
        {
            $file_ary[$i][$key] = $multiple ? $file_post[$key][$i] : $file_post[$key];
        }
    }

    return $file_ary;
}
up
-1
hotmail.com[at]notdefix
8 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
-9
javad dot geek at gmail dot com
2 years 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
-9
contato at dgmike dot com dot br
4 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
-22
ohcnim at hotmail dot com
2 years 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
-10
Pako
5 months ago
If you want to upload multiple file at once, remember "multiple" attribute:

<input type="file" multiple="multiple" name="file[]" enctype="multipart/form-data"/>
up
-3
Roman
3 months ago
function reorganize($files) {
    foreach ($files as $var => $params) {
        foreach ($params as $name => $i) {
            foreach ($i as $num => $val) {
                $images[$var][$name] = $val;
                $arr[$num] = $images;
            }
        }
    }
    return $arr;
}

Array (
     [0] => Array (
         [image] => Array (
             [name] => white-rabbit-med-crop.jpg
             [type] => image/jpeg
             [tmp_name] => E:\xampp\tmp\phpC008.tmp
             [error] => 0
             [size] => 343326 )
        )
    [1] => Array (
         [image] => Array (
             [name] => white-rabbit-med-crop.jpg
             [type] => image/jpeg
             [tmp_name] => E:\xampp\tmp\phpC008.tmp
             [error] => 0
             [size] => 1429802 )
        )
)
To Top