Обработка загруженных файлов

Задача
Необходимо обработать файл, загруженный пользователем.

Решение
Используйте массив $_FILES:
// из if (is_uploaded_file($_FILES['event']['tmp_name'])) {
readfile($_FILES['event']['tmp_name']); // выводим файл на экран
}

Обсуждение
Начиная с версии PHP 4.1 все загруженные файлы появляются в суперглобальном массиве $_FILES. Для каждого файла в нем есть четыре информационных раздела:

name

Имя, присвоенное элементу ввода формы.
type

Тип MIME-файла.
size

Размер файла в байтах.
tmp_name

Временное местоположение файла на сервере.

В более ранних версиях PHP вместо этого массива необходимо использовать массив $HTTP_POST_FILES.1

После выбора файла из массива используйте функцию is_uploaded_file() для подтверждения того, что файл, который нужно обработать, действительно загружен пользователем, затем обработайте его таким же образом, как и другие файлы в системе. Всегда поступайте таким образом. Если вы слепо доверяете именам файлов, предоставленных пользователем, кто-нибудь может изменить запрос и добавить имена, такие как /etc/passwd в список для обработки.

Можно также переместить файл на постоянное местоположение; для безопасного перемещения файла используйте функцию move_uploaded_file():

// перемещаем файл: функция move_uploaded_file() также выполняет
// проверку файлов на легитимность, поэтому нет необходимости
// вызывать еще и функцию is_uploaded_file()
move_uploaded_file($_FILES['event']['tmp_name'], '/path/to/file.txt');

Обратите внимание, что значение, сохраненное в переменной tmp_name, представляет собою полный путь к файлу, а не просто имя файла.


Используйте функцию basename(), чтобы выделить имя, если это необходимо.

Не забудьте убедиться, что PHP имеет права на чтение и запись и в каталоге, куда записываются временные файлы (см. параметр конфигурации upload_tmp_dir для проверки его местоположения) и в каталоге, куда вы собираетесь копировать файл. Часто это может быть пользователь nobody или apache (вместо вашего персонального имени пользователя). Вследствие этого, если вы работаете в режиме safe_mode, после копирования файла в новый каталог, возможно, у вас уже не будет к нему доступа.

Обработка файлов нередко представляет собой нетривиальную задачу, поскольку не все броузеры одинаково представляют одну и ту же информацию. Делать это следует делать очень аккуратно, в противном случае вы можете сами создать брешь в безопасности. В конце концов, злоумышленники могут получить возможность загружать на вашу машину любые файлы, взломать или разрушить вашу систему. Поэтому в PHP реализовано несколько возможностей устанавливать ограничения на загружаемые файлы, включая полный запрет на загрузку любых файлов. Поэтому, если вы испытываете трудности при
обработке загруженных файлов, убедитесь, что файл не отвергается из-за того, что он может представлять риск для безопасности.


Чтобы выполнить такую проверку, сначала убедитесь, что параметр file_uploads в файле конфигурации установлен в оn. Затем проверьте, что размер файла не превышает значение upload_max_filesize; по умолчанию оно равно 2Мбайт, что блокирует чьи-либо попытки разрушить систему путем заполнения жесткого диска гигантскими файлами.

Кроме того, есть параметр post_max_size, контролирующий максимальный размер всех данных POST, разрешенный в одном запросе; начальное значение равно 8 Мбайт.

Вследствие возможных различий в броузерах и ошибок пользователей, если вы не можете получить массив $_FILES для заполнения его информацией, убедитесь, что вы добавили атрибут enctype="multipart/form-data" в открывающий тег формы – это необходимо PHP для запуска обработки. Если вы не можете это сделать, то придется вручную анализировать $HTTP_RAW_POST_DATA. (См. спецификацию MIME в RFC 1521 и 1522 на http://www.faqs.org/rfcs/rfc1521.html и http://www.faqs.org/rfcs/ rfc1522.html.)

Кроме того, если не выбрано ни одного файла для загрузки, то версии PHP до 4.1 устанавливают параметр tmp_name в none; более новые версии присваивают ему пустую строку. Версия PHP 4.2.1 допускает файлы нулевой длины.


Чтобы убедиться, что файл загружен и он не пустой (хотя, в зависимости от обстоятельств, это как раз то, что нужно),
необходимо убедиться, что параметр tmp_name установлен, а значение параметра size больше нуля. И наконец, не все броузеры обязательно посылают тот же тип MIME-файла; то, что они посылают, зависит от того, какие типы файлов они допускают.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Защита от многократной отправки одной и той же формы
Использование элементов формы с несколькими вариантами значений
Кэширование запросов и результатов
Обработка внешних переменных с точками в именах
Обработка информации, полученной из формы

Вернуться в раздел: PHP / 9. Формы