Обработка множественных файлов средствами PHP

Раздел: Программирование на PHP -> Работа с файловой системой

Основные подходы к работе с несколькими файлами

Эффективное решение: отправка массива файлов через HTML форму

Для загрузки нескольких файлов одновременно используется HTML форма с атрибутом enctype="multipart/form-data" и полем ввода типа file с именем, заканчивающимся на квадратные скобки name="files[]". Это позволяет PHP воспринимать все загруженные файлы как массив в суперглобальном массиве $_FILES.


<form method="POST" action="upload.php" enctype="multipart/form-data">
    <input type="file" name="files[]" multiple>
    <button type="submit">Загрузить</button>
</form>

Php get extension (получение информации о файлах в php)

В PHP обработка выглядит так:


$uploadDir = 'uploads/';
if (!empty($_FILES['files']['name'][0])) {
    foreach ($_FILES['files']['name'] as $key => $name) {
        $tmpName = $_FILES['files']['tmp_name'][$key];
        $error = $_FILES['files']['error'][$key];
        if ($error === UPLOAD_ERR_OK) {
            $dest = $uploadDir . basename($name);
            if (move_uploaded_file($tmpName, $dest)) {
                echo "Файл $name загружен успешно.";
            }
        }
    }
}

Php корневой каталог (корневой каталог сайта в php)

Данный подход позволяет обрабатывать неограниченное количество файлов, передаваемых браузером. Атрибут multiple у элемента <input> даёт возможность выбрать несколько файлов в диалоговом окне.

Когда это применяется

  • Галереи изображений
  • Массовая загрузка документов
  • Формы обратной связи с возможностью прикрепления нескольких файлов

Как загрузить несколько файлов через отдельные поля ввода?

Иногда требуется задать фиксированное количество полей для загрузки, например, 3 файла. В этом случае каждое поле получает уникальное имя:


<input type="file" name="file1">
<input type="file" name="file2">
<input type="file" name="file3">

Php база в файле (хранение данных в файлах в php (flat-file database))

Обработчик должен проверять каждое поле отдельно:


for ($i = 1; $i <= 3; $i++) {
    $field = 'file'.$i;
    if (!empty($_FILES[$field]['name'])) {
        // обработка
    }
}

Php include server (include сервера php)

Такой способ используется, когда количество файлов строго определено и заранее известно.

Возможные проблемы:

  • Ограничение максимального размера запроса в php.ini (post_max_size, upload_max_filesize). При загрузке больших файлов может возникнуть ошибка. Решение: увеличить соответствующие директивы.
  • Превышение времени выполнения скрипта. Для обработки множества файлов следует установить set_time_limit(0) или увеличить лимит.
  • Конфликт имен файлов. Пользователь может загрузить файлы с одинаковыми именами. Рекомендуется использовать уникальные имена, например, с добавлением временной метки или случайной строки.

Как обработать несколько файлов, переданных через массив с другими структурами (например, массив массивов)?

Структура $_FILES не всегда удобна. Альтернативой является реорганизация массива в плоскую структуру. Для этого используется функция для перегруппировки:


function reorganizeFiles($filePost) {
    $files = [];
    foreach ($filePost as $key => $all) {
        foreach ($all as $i => $val) {
            $files[$i][$key] = $val;
        }
    }
    return $files;
}
$files = reorganizeFiles($_FILES['files']);

Php несколько файлов (несколько файлов в php)

Теперь каждый элемент $files[$i] содержит обычный набор полей (name, tmp_name и т.д.). Это упрощает перебор.

Как осуществить загрузку нескольких файлов с использованием cURL и PHP?

Для отправки нескольких файлов на другой сервер используется библиотека cURL. Формируется массив с ключами в стиле files[0]:


$ch = curl_init();
$post = [
    'files[0]' => new CURLFile('/path/to/file1.txt'),
    'files[1]' => new CURLFile('/path/to/file2.jpg')
];
curl_setopt($ch, CURLOPT_URL, 'http://example.com/upload.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_exec($ch);

Php файл с сервера (файл с сервера php)

На принимающей стороне файлы будут доступны так же, как при обычной форме.

Как прочитать содержимое нескольких файлов одновременно (без загрузки через форму)?

Иногда требуется обработать уже существующие на сервере файлы. Для этого используется функция glob() или scandir().


$files = glob('data/*.txt');
foreach ($files as $file) {
    $content = file_get_contents($file);
    echo "Содержимое $file: $content";
}

Этот подход удобен для пакетной обработки логов или экспорта данных.

Типичные ошибки:

  • Отсутствие прав на чтение/запись директорий. Следует проверять is_readable() и is_writable().
  • Игнорирование символических ссылок. Функция is_file() поможет отличить файлы от ссылок.
- Php текстовый файл (текстовый файл php)
- Php изменить файл (изменение файла в php)
- Php размер файла (размер файла php)

Расширенные примеры работы с несколькими файлами

Пример 1: Загрузка файлов с проверкой MIME-типа и размера

Валидация каждого файла по типу (только изображения) и максимальному размеру (5 МБ). В случае ошибки формируется массив с сообщениями.

Пример

$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
$maxSize = 5 * 1024 * 1024; // 5 MB
$errors = [];
$uploadDir = 'uploads/';

foreach ($_FILES['files']['tmp_name'] as $key => $tmpName) {
    if ($_FILES['files']['error'][$key] !== UPLOAD_ERR_OK) {
        $errors[] = "Ошибка загрузки файла {$_FILES['files']['name'][$key]}";
        continue;
    }
    if ($_FILES['files']['size'][$key] > $maxSize) {
        $errors[] = "Файл {$_FILES['files']['name'][$key]} превышает 5 МБ";
        continue;
    }
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $tmpName);
    finfo_close($finfo);
    if (!in_array($mime, $allowedTypes)) {
        $errors[] = "Тип файла {$_FILES['files']['name'][$key]} не разрешен";
        continue;
    }
    $ext = pathinfo($_FILES['files']['name'][$key], PATHINFO_EXTENSION);
    $newName = uniqid() . '.' . $ext;
    if (move_uploaded_file($tmpName, $uploadDir . $newName)) {
        echo "Файл {$_FILES['files']['name'][$key]} сохранён как $newName<br>";
    }
}
if (!empty($errors)) {
    echo implode('<br>', $errors);
}

Результат (пример вывода):

Файл photo1.jpg сохранён как 67a12b3c4d5e6.jpg
Файл photo2.png сохранён как 67a12b3c4d5e7.png
Тип файла document.pdf не разрешен

Пример 2: Асинхронная загрузка нескольких файлов через AJAX с отображением прогресса

На стороне клиента используется XMLHttpRequest с отслеживанием прогресса загрузки каждого файла. На сервере файлы обрабатываются стандартным способом. Для удобства файлы передаются в виде массива.

Пример

// JavaScript (упрощённо)
let formData = new FormData();
let files = document.getElementById('fileInput').files;
for (let i = 0; i < files.length; i++) {
    formData.append('files[]', files[i]);
}
let xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function(e) {
    if (e.lengthComputable) {
        let percent = Math.round((e.loaded / e.total) * 100);
        console.log('Общий прогресс: ' + percent + '%');
    }
});
xhr.open('POST', 'upload.php', true);
xhr.send(formData);

Серверная часть (upload.php) может возвращать JSON с результатами:

Пример

$response = [];
foreach ($_FILES['files']['name'] as $key => $name) {
    // ... обработка как в примере 1 ...
    $response[] = ['name' => $name, 'status' => 'success'];
}
echo json_encode($response);

Пример 3: Пакетное переименование и перемещение файлов с использованием итератора

Пример

$sourceDir = '/var/www/incoming';
$destDir = '/var/www/processed';
$it = new DirectoryIterator($sourceDir);
foreach ($it as $fileInfo) {
    if ($fileInfo->isFile()) {
        $newName = 'processed_' . $fileInfo->getFilename();
        rename($fileInfo->getPathname(), $destDir . '/' . $newName);
    }
}

Результат: все файлы из папки incoming получают префикс processed_ и перемещаются в processed.

Пример 4: Загрузка ZIP-архива и его распаковка на сервере

Пример

if ($_FILES['archive']['error'] === UPLOAD_ERR_OK) {
    $zip = new ZipArchive();
    if ($zip->open($_FILES['archive']['tmp_name']) === TRUE) {
        $zip->extractTo('extracted/');
        $zip->close();
        echo 'Архив распакован.';
    } else {
        echo 'Не удалось открыть архив.';
    }
}

Перед распаковкой следует проверять структуру архива на предмет вредоносных файлов.

Несколько файлов в PHP - comments

En
Php несколько файлов (php)