PHP 8.6.0 Beta 1 is available for testing

Загрузка нескольких файлов

Набор файлов загружают через разные значения атрибута name в input-элементах формы.

Возможно также загружать набор файлов одновременно и автоматически получать файлы в виде массива. Для этого в HTML-форме пользуются тем же синтаксисом отправки массива, что и для отправки списка значений через HTML-элементы SELECT или поля ввода с типом checkbox:

Пример #1 Загрузка нескольких файлов

<form action="file-upload.php" method="post" enctype="multipart/form-data">
 Файлы:<br />
 <input name="userfile[]" type="file" /><br />
 <input name="userfile[]" type="file" /><br />
 <input type="submit" value="Отправить" />
</form>

При отправке приведённой формы PHP инициализирует массивы $_FILES['userfile'] , $_FILES['userfile']['name'] и $_FILES['userfile']['size'] .

Предположим, что отправили файлы /home/test/review.html и /home/test/xwp.out. Тогда переменная $_FILES['userfile']['name'][0] будет содержать значение review.html, а переменная $_FILES['userfile']['name'][1] xwp.out. Аналогично, переменная $_FILES['userfile']['size'][0] будет содержать размер файла review.html и так далее.

PHP также инициализирует переменные $_FILES['userfile']['name'][0] , $_FILES['userfile']['tmp_name'][0] , $_FILES['userfile']['size'][0] и $_FILES['userfile']['type'][0] .

Внимание

Параметр конфигурации max_file_uploads ограничивает количество файлов, которое разрешается загружать за один запрос. Потребуется проверить, что форма не пытается загрузить за один запрос больше файлов, чем ограничение.

Пример #2 Загрузка каталога

В HTML-полях выбора файла для загрузки указывают атрибут webkitdirectory, чтобы загрузить весь каталог. Бо́льшая часть браузеров поддерживает эту функцию.

Информация, которую хранит элемент full_path, помогает сохранить относительные пути или воссоздать такой же каталог на сервере.

<form action="file-upload.php" method="post" enctype="multipart/form-data">
 Загрузка каталога:<br />
 <input name="userfile[]" type="file" webkitdirectory multiple />
 <input type="submit" value="Загрузить файлы" />
</form>
Внимание

Атрибут webkitdirectory нестандартен и не соответствует спецификациям. Не рекомендуется включать атрибут в элементы форм на рабочих сайтах: атрибут работает не у каждого пользователя. Способ обработки атрибута несовместим между браузерами, и поведение могут изменить в будущих выпусках.

PHP анализирует только информацию об относительном пути, которую отправили браузер или пользовательский агент, и передаёт информацию в суперглобальный массив $_FILES . Нет гарантии, что значения в массиве full_path содержат реальную структуру каталогов, и PHP-приложение не должно доверять этой информации.

Нашли ошибку?

ИнструкцияИсправлениеСообщение об ошибке
+Добавить

Примечания пользователей 8 notes

up
357
phpuser at gmail dot com
21 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
18
i.g.e.o@ya (dot) ru
6 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
12 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
14
Corey Ballou
16 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
14 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
1
sabryabdelmohsen at gmail dot com
5 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;
}
up
5
lookphp at gmail dot com
10 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
<?php
echo '<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
2 years 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
}
+Добавить

AltStyle によって変換されたページ (->オリジナル) /