Автоматическая загрузка файлов php на сервер. Отдаем файлы эффективно с помощью PHP. Файл успешно загружен на сервер


Что может быть общего у фотографий, находящихся в онлайн-фотоальбоме, прикреплённых к электронному письму или у файлов, представленных в онлайн-приложении для пакетной обработки? Всех их необходимо загрузить на сервер через интернет из веб-браузера. Действительно, загрузка файлов является важной особенностью многих сайтов и веб-приложений, которые мы используем ежедневно. Из этой статьи вы узнаете, как добавить к себе на сайт поддержку загрузки файлов используя для этого PHP.

Требования перед загрузкой файлов

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

File_uploads = On

Загружаемые файлы сначала сохраняются во временном каталоге (но не волнуйтесь... ваш PHP-скрипт впоследствии может переместить файлы в более подходящее место). Исходное местоположение является временным каталогом для системы по умолчанию. Вы можете указать другой каталог, используя директиву upload_tmp_dir в php.ini. Независимо от этого, будет не лишним проверить, что процесс PHP имеет правильные права на запись в зависимости от используемого каталога.

Upload_tmp_dir = "/tmp" tboronczyk@zarkov:~$ ls -l / | grep tmp drwxrwxrwt 13 root root 40960 2011-08-31 00:50 tmp

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

использовал метод POST и имел атрибут enctype , установленный для multipart/form-data .

Этапы загрузки файла на сервер

Скорей всего, вы уже можете представить, как загружаются файлы на сервер, основываясь на собственном опыте и требованиях о которых я упомянул выше.

  • Посетитель просматривает HTML-страницу с формой, специально написанной для поддержки загрузки файлов;
  • Далее он предоставляет файл, который он хочет загрузить и нажимает кнопку отправить;
  • Браузер кодирует файл и отправляет его как часть запроса POST;
  • PHP получает форму отправки, декодирует файл и сохраняет его во временном месте на сервере;
  • Написанный PHP-скрипт, ответственный за обработку сообщения формы, проверяет файл и обрабатывает его каким-то образом, часто перемещая его из своего временного местоположения в постоянное, где будет храниться файл.

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

Добавляем HTML форму для загрузки файла

HTML-формы предоставляют собой интерфейс, через который пользователь инициирует загрузку файла. Нужно помнить, что элемент должен иметь свой атрибут метода, установленный для публикации, и его атрибут enctype , заданный для multipart/form-data . Элемент файла предоставляет поле, используемое для указания файла, который будет загружен. Как и любой другой элемент формы, важно указать атрибут имени, чтобы вы могли ссылаться на него в PHP скрипте, обрабатывающем форму.

Вот как выглядит типичная разметка формы загрузки файлов:


Стоит отметить, что разные браузеры будут визуализировать поле загрузки файла по-разному. IE, Firefox и Opera отображают его как текстовое поле с кнопкой рядом с ней надписью «Обзор» или «Выбрать». Safari отображает ее так же, как кнопку с надписью: «Выбрать файл». По большому счету это не проблема с тех пор, как пользователи привыкли к тому, как поле отображается в своем браузере и умеют его использовать. Иногда, однако, вы столкнетесь с клиентом или дизайнером, который непреклонно представляет его определенным образом. Количество CSS и JavaScript, которые могут применяться к файловому полю, крайне ограничено из-за соображений о безопасности, наложенных браузерами. Типизация файла может быть затруднена. Если внешний вид очень важен для вас, я рекомендую вам прочитать одну из статей «Питер-Пол Кох» типа ввода = «файл» .

Переходим на сервере и работаем с PHP

Информация о загрузке файла предоставляется с помощью многомерного массива $_FILES . Этот массив обладает своей структурой, назначенными именами для полей файла в форме HTML, точно так же, как и при работе с $_GET и $_POST . Затем массив каждого файла содержит следующие элементы:

  • $_FILES["myFile"]["name"] - хранит исходное имя файла;
  • $_FILES["myFile"]["type"] - сохраняет mime-типа файла;
  • $_FILES["myFile"]["size"] - сохраняет размер файла (в байтах);
  • $_FILES["myFile"]["tmp_name"] - хранит имя временного файла;
  • $_FILES["myFile"]["error"] - хранит код ошибки, полученный в результате передачи.

При помощи функции move_uploaded_file() мы можем перенести файл из своего временного каталога в постоянное место. Так же хорошей практикой является использовать именно её вместо copy() и rename() для этой цели, поскольку она выполняет дополнительные проверки, чтобы гарантировать, что файл был действительно загружен запросом HTTP методом POST.

Если вы собираетесь сохранить файл с исходным именем, предоставленным пользователем, рекомендуется убедиться, что это безопасно. Имя файла не должно содержать символов, которые могут повлиять на путь назначения, например, косая черта (слэш). Имя файла должно быть уникальным, чтоб избежать затирания существующих с тем же именем (если это не предусматривается вашим приложением). Гарантировать это можно заменяя любые символы символом подчеркивания, который не является буквой, а затем добавляя увеличивающийся номер, если файл с таким именем уже существует.

Вот так как выглядит получение и обработка загрузки файла при помощи PHP:

Define("UPLOAD_DIR", "/srv/www/uploads/"); if (!empty($_FILES["myFile"])) { $myFile = $_FILES["myFile"]; if ($myFile["error"] !== UPLOAD_ERR_OK) { echo "

Произошла ошибка.

"; exit; } // обеспечиваем безопасное имени файла $name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]); // не перезаписываем существующий файл $i = 0; $parts = pathinfo($name); while (file_exists(UPLOAD_DIR . $name)) { $i++; $name = $parts["filename"] . "-" . $i . "." . $parts["extension"]; } // сохраняем файл из временного каталога $success = move_uploaded_file($myFile["tmp_name"], UPLOAD_DIR . $name); if (!$success) { echo ""; exit; } // устанавливаем правильные права для нового файла chmod(UPLOAD_DIR . $name, 0644); }

Сначала мы удостоверяемся, что PHP загрузка файла на сервер прошла без ошибок. Затем определяем безопасное имя файла, как я только что описал выше, а затем перемещаем файл в его конечный каталог с помощью move_uploaded_file() . И наконец делаем вызов chmod() , чтобы убедиться, что в новом файле установлены необходимые права доступа.

Вопросы безопасности

Один из них заключается в том, чтобы проверить тип загружаемого файла, каким он должен быть. Опираться на значение $_FILES["myFile"]["type"] или на расширение имени файла не является безопасным, поскольку оба могут легко подделываться. Скорее, используйте функцию exif_imagetype() , чтобы проверить содержимое файла и определить, действительно ли это GIF, JPEG или один из нескольких других поддерживаемых форматов изображений. Если exif_imagetype() недоступен (функция требует, чтобы расширение Exif было включено), вы можете использовать getimagesize() . Массив, возвращаемый ей, будет содержать тип изображения, если он распознан.

// проверяем файл GIF, JPEG или PNG $fileType = exif_imagetype($_FILES["myFile"]["tmp_name"]); $allowed = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG); if (!in_array($fileType, $allowed)) { // тип файла не разрешен...

Для файлов без изображения вы можете использовать exec() для вызова утилиты файлов unix. он определяет тип файла, ища известные двоичные подписи в ожидаемых местах.

// проверяем файл в формате PDF $mime = "application/pdf; charset=binary"; exec("file -bi " . $_FILES["myFile"]["tmp_name"], $out); if ($out != $mime) { // файл не PDF ...

Еще один шаг, который вы можете предпринять, - наложить жесткие ограничения на общий размер запроса POST и количество файлов, которые можно загрузить. Для этого укажите соответствующее значение для директив upload_max_size , post_max_size и max_file_uploads в php.ini. Директива upload_max_size указывает максимальный размер загрузки файла. В дополнение к размеру загрузки вы можете ограничить размер всего запроса POST директивой post_max_size . max_file_uploads - это новая директива (добавлена в версии 5.2.12), которая ограничивает количество загрузок файлов. Эти три директивы помогают защитить ваш сайт от атак, которые пытаются нарушить его доступность, вызывая интенсивный сетевой трафик или загрузку системы.

Post_max_size = 8M upload_max_size = 2M max_file_uploads = 20

Третий шаг, который вы можете предпринять для минимизации риска, - это сканирование загруженных файлов с помощью антивирусного сканера. Это жизненно важно для защиты от распространённых вирусов и вредоносных программ, особенно если ваш сайт осуществляет файлообмен между разными людьми, как пример - вложения в веб-почтовый клиент или (юридический) сайт для обмена файлами. Существует расширение PHP, которое обеспечивает доступ к ClamAV , но, конечно, вы можете вызвать утилиту командной строки ClamAV так же, как я продемонстрировал для файла.

Exec("clamscan --stdout " . $_FILES["myFile"]["tmp_name"], $out, $return); if ($return) { // файл заражен...

Подводим итоги и делаем выводы

Сегодня вы узнали, как происходит настройка и осуществляется процесс PHP загрузки файлов на сервер с вашего сайта или веб-приложения. Чтобы загрузка была успешной, форма HTML должна быть отправлена через запрос POST с множественным форматированием данных, а PHP должен разрешать передачу, как указано, с помощью директивы file_uploads . После переноса файла, сценарий, ответственный за обработку загрузки, использует информацию, найденную в массиве $_FILES , чтобы переместить файл из временного каталога в нужное место. Я также поделился некоторыми дополнительными мерами предосторожности, которые вы можете предпринять, чтобы защитить себя и своих пользователей от некоторых рисков, связанных с возможностью загрузки файлов. Чтобы гарантировать свою безопасность - проверяйте тип файла, наложите жесткие ограничения на загрузку трафика и применяйте сканирование на наличие вирусов.

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

Для того чтобы можно было загружать на сервер один или несколько файлов, в форме применяется специальное поле. В браузерах Firefox, IE и Opera такой элемент отображается как текстовое поле, рядом с которым располагается кнопка с надписью «Обзор...» (рис. 1). В Safari и Chrome доступна только кнопка «Выберите файл» (рис. 2).

Рис. 1. Вид поля для загрузки файла в Firefox

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

Синтаксис поля для отправки файла следующий.

Атрибуты перечислены в табл. 1.

Прежде, чем использовать данное поле, в форме необходимо сделать следующее:

  1. задать метод отправки данных POST (method="post" );
  2. установить у атрибута enctype значение multipart/form-data .

Форма для загрузки файла продемонстрирована в примере 1.

Пример 1. Создание поля для отправки файла

HTML5 IE Cr Op Sa Fx

Отправка файла на сервер

Хотя можно установить ширину поля через атрибут size , в действительности ширина никак не влияет на результат работы формы. В браузерах Safari и Chrome этот атрибут вообще никакого воздействия не оказывает.

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

Если атрибут accept не указывать, тогда добавляются и загружаются файлы любого типа. Наличие accept позволяет ограничить выбор файла, что особенно важно, когда требуется загрузить только изображение или видео. В качестве значения выступает , несколько значений разделяются между собой запятой. Также можно использовать следующие ключевые слова:

  • audio/* - выбор музыкальных файлов любого типа;
  • image/* - графические файлы;
  • video/* - видеофайлы.

В табл. 2 показаны некоторые допустимые значения атрибута accept .

Использование дополнительных атрибутов показано в примере 2.

HTML5 IE 10+ Cr Op Sa Fx

Загрузите ваши фотографии на сервер

Не все браузеры поддерживают новые атрибуты. IE полностью игнорирует multiple и accept , Safari не поддерживает accept , а Firefox не работает с MIME-типом, только с ключевыми словами. Поэтому в примере выше специально для Firefox установлено значение image/*,image/jpeg . Также учтите странную ошибку в Опере, она не допускает пробелы после запятой внутри accept .

Результат примера показан на рис. 3. Обратите внимание, что из-за наличия multiple несколько изменился вид поля.

Как загрузить файл на сервер используя PHP? В этой статье мы подробно рассмотрим этот вопрос с примерами.

HTML-форма для отправки файла

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

Вот пример HTML-кода такой формы:

Форма для загрузки файлов



Что уникального в этой форме:

  1. Тег form должен обязательно содержать атрибут enctype="multipart/form-data . Именноо этот атрибут указывает на то, что форма будет передавать файл. По умолчанию атрибут enctype имеет значение application/x-www-form-urlencoded .
  2. Форма должна содержать скрытый атрибут (type="hidden") с именем MAX_FILE_SIZE в значении которого (value) указывается размер файла. Теоретически, браузеры должны сообщать о том, что файл превышает допустимые размеры, но на практике браузеры не поддерживают это. Я думаю, что этот атрибут можно не указывать.
  3. Для выбора передаваемого файла служит тег input , у которого атрибут type="file" .

После того, как сервер получил HTTP-запрос от такой формы, он записывает файл во временную папку на сервере.

Если хотите чтобы файл на этом этапе сохранялся в другой каталог, укажите его в директиве upload_tmp_dir файла php.ini.

Для перемещения загруженного файла в новое место используется функция move_uploaded_file .

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

Итак, после того, как скрипт получил данные формы с переданным файлом, файл он записал в специальную папку, а данные о файле записал в двумерный массив $_FILES .

Давайте рассмотрим пример, который выводит содержимое массива $_FILES на экран.

Форма для загрузки файлов


"; } else { echo "
", print_r($_FILES), "
"; } ?>

Вот что мы получим в результате работы этого скрипта:

Рис.1. Массив $_FILES.

Теперь давайте разберём, что содержится в этом массиве.

В нашем двумерном массиве $_FILES есть один элемент filename . Это значение поля name из элемента формы:

Данные для этого файла:

  • $_FILES["filename"]["name"] - имя файла;
  • $_FILES["filename"]["type"] - тип файла;
  • $_FILES["filename"]["tmp_name"] - полный путь к временному каталогу на диске;
  • $_FILES["filename"]["error"] - содержит код ошибки, который это 0, если операция прошла успешно;
  • $_FILES["filename"]["size"] - размер файла.

Можно было бы в форме указать два поля для файлов, например так:


В этом случае наш массив выглядел бы так:


Рис.2. Массив $_FILES.

Итак, теперь мы знаем как устроен массив $_FILES и следующий шаг - положить полученный файл в нужное нам место.

Функция move_uploaded_file

Как я уже писал, для перемещения загруженного файла в новое место используется функция move_uploaded_file .

Синтаксис функции move_uploaded_file:

move_uploaded_file (откуда переносить, куда переносить)

Функция move_uploaded_file возвращает булево значение:

  • TRUE - в случае успеха,
  • FALSE - если первый аргумент является загруженным файлом, но по каким-либо причинам не может быть перемещён в указанное место, в этом случае никаких действий не предпринимается.

Используем эту функцию в примере:

Форма для загрузки файлов


"; } else { move_uploaded_file ($_FILES["filename"]["tmp_name"], __DIR__ . DIRECTORY_SEPARATOR . $_FILES["filename"]["name"]); } ?>

Этот скрипт перемещает картинку в ту же папку, в которой он сам находится. Для этого мы используем встроенные в PHP константы для указания пути:

  • __DIR__ - одна из "волшебных" констант, содержит директорию файла.
  • DIRECTORY_SEPARATOR - предопределённая константа, содержащая разделитель пути. Для ОС Windows это «\», для ОС Linux и остальных - «/».

Внимание: Если результирующий файл уже существует, он будет перезаписан.

Функция is_uploaded_file

Ест ещё одна функция, которую нужно обязательно использовать при работе с загрузкой файлов на сервер. Это функция is_uploaded_file и она используется из соображений безопасности.

is_uploaded_file - определяет, был ли файл загружен при помощи HTTP POST и возвращает TRUE, если это так.

Использование этой функции целесообразно для удостоверения, что злонамеренный пользователь не пытается обмануть скрипт так, чтобы он работал с файлами, с которыми работать не должен - к примеру, /etc/passwd .

Обратите внимание: для правильной работы функции is_uploaded_file нужно передать путь к файлу на временном хранилище на сервере, то есть аргумент вида $_FILES["filename"]["tmp_name"] , - а вот имя закачиваемого файла на клиентской машине ($_FILES["filename"]["name"]) тут не подходит.

Наш конечный пример скрипта, обрабатывающего форму отправки файла, будет выглядеть так:

Форма для загрузки файлов


"; } else { // Проверяем загружен ли файл if(is_uploaded_file($_FILES["filename"]["tmp_name"])) { // Если файл загружен успешно, перемещаем его // из временной директории в конечную move_uploaded_file ($_FILES["filename"]["tmp_name"], __DIR__ . DIRECTORY_SEPARATOR . $_FILES["filename"]["name"]); } else { echo("Ошибка загрузки файла"); } } ?>

Ограничиваем размер файла

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

1024*3*1024) { echo("Размер файла превышает три мегабайта"); exit; } ... ?>

Максимальный размер загружаемого файла можно также задать при помощи директивы upload_max_filesize в файле в php.ini. Значение этой которой директивы по умолчанию равно 2 Мбайт:

$upload_max_filesize) ... ?>

Настройки php.ini для загрузки файлов на сервер

Итак, мы узнали про директиву upload_max_filesize файла php.ini которая устанавливает максимальный размер загружаемого файла. Какие ещё директивы файла php.ini отвечают за загрузку файлов на сервер?

Кстати, если Вы хотите узнать, где расположен Ваш файл php.ini, выполните скриптик:

Итак, список директив файла php.ini:

  • file_uploads - возможность запретить или разрешить загрузку файлов на сервер в целом, по умолчанию разрешена (значение On).
  • post_max_size - общее ограничение сверху на размер данных, передаваемых в POST запросе. Если Вам необходимо передавать несколько файлов одновременно, или работать с большими файлами, измените значение этой директивы. Значение по умолчанию 8Мб.
  • upload_max_filesize - уже рассмотренная нами директива. Не забывайте при необходимости также менять post_max_size .
  • upload_tmp_dir - временная директория на сервере, в которую будут помещаться все загружаемые файлы.

Это всё, что я хотел сказать Вам по теме "Загрузка файлов на сервер в PHP".

Multipart-формы

  • Веб-итерфейсы почтовых сервисов, которые позволяют добавалять к письму приложение (attach), а для этого нужно сначала загрузить файл на сервер, и только после этого его можно добавлять к письму;
  • Интерактивные фотогалереи и фотоальбомы, которые не могут существовать без механизма загрузки файлов на сервер;
  • Порталы бесплатного програмного обеспечения, которые используют для обмена файлами различных программ, и.т.д.

Загрузка файла на сервер осуществляется с помощью multipart -формы, в которой есть поле загрузки файла. В качестве параметра enctype указывается значение multipart/form-data :



Вот так примерно будет выглядеть приведенная multipart-форма (вы можете попробовать с ее помощью посмотреть результат работы multipart-форм, загрузив какой-нибудь файл небольшого размера на сервер):

Multipart-формы обычно используют метод передачи POST. Как видно из предыдущего примера, данная форма имеет два поля:

  • Поле выбора файла для закачки ;
  • Поле указания имени файла, которое он должен будет иметь на сервере .

Обработка multipart-форм

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

Конфигурационный файл PHP php.ini имеет три параметра, связанные с загрузкой файлов на сервер:

  • file_uploads=On - разрешает загрузку файлов на сервер по протоколу HTTP;
  • upload_tmp_dir=/tmp - устанавливает каталог для временного хранения загруженных файлов;
  • upload_max_filesize=2M - устанавливает максимальный объем загружаемых файлов.

Если ваш веб-сервер работает под управлением операционной системы Linux, то нужно перезапустить сервис:

service httpd restart

Как же PHP обрабатывает multipart-формы? Получив файл, он сохраняет его во временном каталоге upload_tmp_dir , имя файла выбирается случайным образом. Затем он создает четыре переменных суперглобального массива $_FILES . Этот массив содержит информацию о загруженном файле.

Переменные, определенные для загруженных файлов, зависят от версии PHP и текущей конфигурации. Суперглобальный массив $_FILES доступен начиная с PHP 4.1.0. В случае, если конфигурационная директива register_globals установлена значением on , дополнительно будут объявлены переменные с соответствующими именами. Начиная с версии 4.2.0 значением по умолчанию для опции register_globals является off .

Содержимое массива $_FILES для нашего примера приведено ниже. Обратите внимание, что здесь предполагается использование имени uploadfile для поля выбора файла, в соответствии с приведенной выше multipart-форме. Разумеется, имя поля может быть любым.

  • $_FILES["uploadfile"]["name"] - имя файла до его отправки на сервер, например, pict.gif;
  • $_FILES["uploadfile"]["size"] - размер принятого файла в байтах;
  • $_FILES["uploadfile"]["type"] - MIME-тип принятого файла (если браузер смог его определить), например: image/gif, image/png, image/jpeg, text/html;
  • (так мы назвали поле загрузки файла) - содержит имя файла во временном каталоге, например: /tmp/phpV3b3qY;
  • $_FILES["uploadfile"]["error"] - Код ошибки, которая может возникнуть при загрузке файла. Ключ ["error"] был добавлен в PHP 4.2.0. С соответствующими кодами ошибок вы можете ознакомиться

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

Если кнопка "Submit" нажата, то файл уже будет загружен на сервер и его имя будут в переменной $_FILES["uploadfile"]["name"] . В этом случае скрипт должен сразу скопировать файл с именем $_FILES["uploadfile"]["tmp_name"] в какой-нибудь каталог (необходимы права на запись в этот каталог).

Копирование файла производится функцией copy() :

Используйте только функцию копирования copy() , а не перемещения, поскольку:

  • Временный файл будет удален автоматически;
  • Если временный каталог находится на другом носителе, будет выведено сообщение об ошибке.

Предположим, нам нужно загрузить файл в каталог uploads , который находится в корневом каталоге веб-сервера (в каталоге DocumentRoot ).

// На всякий случай создадим каталог. Если он уже создан,
// сообщение об ошибки мы не увидим, поскольку воспользуемся оператором @:

@mkdir("uploads", 0777);

// Копируем файл из /tmp в uploads
// Имя файла будет таким же, как и до отправки на сервер:

Copy($_FILES["uploadfile"]["tmp_name"],"uploads/".basename($_FILES["uploadfile"]["name"]));

В Linux все намного сложнее - нам нужно учитывать права доступа к каталогу uploads . Скорее всего в таком случае, функция mkdir() не сработает, так как у нас нет прав на запись в каталог DocumentRoot (обычно это /var/www/html или /home/httpd/html). Зарегистрируйтесь в системе как пользователь root , создайте каталог uploads и измените его владельца и права доступа следующим образом:

// Создаем каталог uploads

// Устанавливаем имя владельца apache и его группу - тоже apache:

Chown apache:apache uploads

// Разрешение записи всем (777) + установка закрепляющего бита (1):

Chmod 1777 uploads

Размер файла можно ограничить, при желании можно отредактировать файл .htaccess и ограничить доступ к каталогу uploads - указать или конкретных пользователей, которым можно обращаться к каталогу, или IP-адреса.

Вот теперь можно загружать файлы на сервер.

Пишем PHP скрипт загрузки файлов на сервер


// Каталог, в который мы будем принимать файл:
$ uploaddir = "./files/" ;
$ uploadfile = $ uploaddir . basename ($ _FILES [ "uploadfile" ][ "name" ]);

// Копируем файл из каталога для временного хранения файлов:
if (copy ($ _FILES [ "uploadfile" ][ "tmp_name" ], $ uploadfile ))
{
echo "

Файл успешно загружен на сервер

" ;
}
else { echo "

Ошибка! Не удалось загрузить файл на сервер!

"
; exit ; }

// Выводим информацию о загруженном файле:
echo "

Информация о загруженном на сервер файле:

"
;
echo "

Оригинальное имя загруженного файла: " .$ _FILES [ "uploadfile" ][ "name" ]. "

" ;
echo "

Mime-тип загруженного файла: " .$ _FILES [ "uploadfile" ][ "type" ]. "

" ;
echo "

Размер загруженного файла в байтах: " .$ _FILES [ "uploadfile" ][ "size" ]. "

" ;
echo "

Временное имя файла: " .$ _FILES [ "uploadfile" ][ "tmp_name" ]. "

" ;

?>

Загрузку нескольких файлов можно реализовать используя, например, различные значения name для тега input .

Также предусмотрена возможность автоматического получения организованной в массив информации о нескольких одновременно загружаемых файлах. Для реализации такой возможности используйте тот же синтаксис отправки массива из HTML-формы, что и для множественных полей select и checkbox :


Send these files:






В случае, если такая форма была отправлена, массивы $_FILES["userfile"] , $_FILES["userfile"]["name"] , и $_FILES["userfile"]["size"] будут инициализированы (точно так же, как и $HTTP_POST_FILES для PHP 4.1.0 и более ранних версий). Если конфигурационная директива register_globals установлена значением on , также будут инициализированы сопутствующие глобальные переменные. Каждая из таких переменных будет представлять собой численно индексированный массив соответствующих значений для принятых файлов.

Предположим, что были загружены файлы /home/test/some.html и /home/test/file.bin . В таком случае переменная $_FILES["userfile"]["name"] будет иметь значение some.html , а переменная $_FILES["userfile"]["name"] - значение file.bin . Аналогично, переменная $_FILES["userfile"]["size"] будет содержать размер файла some.html и так далее.

Переменные $_FILES["userfile"]["name"] , $_FILES["userfile"]["tmp_name"] , $_FILES["userfile"]["size"] и $_FILES["userfile"]["type"] также будут инициализированы.

Заключение:

Как видите, организовать загрузку файлов на сервер не так сложно. Сложнее обеспечить необходимый уровень безопасности, так как загрузка файлов на сервер может использоваться злоумышленниками для атаки на сервер. О том, как обеспечить необходимый уровень безопасности, работая с Uploads , смотрите .



<<< Назад Содержание Вперед >>>
Есть еще вопросы или что-то непонятно - добро пожаловать на наш

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

PHP способен получать загруженные файлы из любого браузера, совместимого со стандартом RFC-1867.

Также следует заметить, что PHP поддерживает загрузку файлов методом PUT, который используется в клиентах Netscape Composer и W3C Amaya . Для получения более детальной документации обратитесь к разделу поддержка метода PUT

Пример #1 Форма для загрузки файлов

Страница для загрузки файлов может быть реализована при помощи специальной формы, которая выглядит примерно так:

Отправить этот файл:

В приведенном выше примере __URL__ необходимо заменить ссылкой на PHP-скрипт.

Скрытое поле MAX_FILE_SIZE (значение необходимо указывать в байтах) должно предшествовать полю для выбора файла, и его значение является максимально допустимым размером принимаемого файла в PHP. Рекомендуется всегда использовать эту переменную, так как она предотвращает тревожное ожидание пользователей при передаче огромных файлов, только для того, чтобы узнать, что файл слишком большой и передача фактически не состоялась. Помните, обойти это ограничение на стороне браузера достаточно просто, следовательно, вы не должны полагаться на то, что все файлы большего размера будут блокированы при помощи этой возможности. Это по большей части удобная возможность для пользователей клиентской части вашего приложения. Тем не менее, настройки PHP (на сервере) касательно максимального размера обойти невозможно.

Замечание :

Также следует убедиться, что в атрибутах формы вы указали enctype="multipart/form-data" , в противном случае загрузка файлов на сервер выполняться не будет.

Оригинальное имя файла на компьютере клиента.

$_FILES["userfile"]["type"]

Mime-тип файла, в случае, если браузер предоставил такую информацию. Пример: "image/gif" . Этот mime-тип не проверяется в PHP, так что не полагайтесь на его значение без проверки.

$_FILES["userfile"]["size"]

Размер в байтах принятого файла.

Временное имя, с которым принятый файл был сохранен на сервере.

$_FILES["userfile"]["error"]

Код ошибки , которая может возникнуть при загрузке файла.

По умолчанию принятые файлы сохраняются на сервере в стандартной временной папке до тех пор, пока не будет задана другая директория при помощи директивы upload_tmp_dir конфигурационного файла php.ini . Директорию сервера по умолчанию можно сменить, установив переменную TMPDIR для окружения, в котором выполняется PHP. Установка этой переменной при помощи функции putenv() внутри PHP-скрипта работать не будет. Эта переменная окружения также может использоваться для того, чтобы удостовериться, что другие операции также работают с принятыми файлами.

Пример #2 Проверка загружаемых на сервер файлов

Для получения более детальной информации вы можете ознакомиться с описанием функций is_uploaded_file() и move_uploaded_file() . Следующий пример принимает и обрабатывает загруженный при помощи формы файл.

// В PHP 4.1.0 и более ранних версиях следует использовать $HTTP_POST_FILES
// вместо $_FILES.

$uploaddir = "/var/www/uploads/" ;
$uploadfile = $uploaddir . basename ($_FILES [ "userfile" ][ "name" ]);

echo "

"
;
if (move_uploaded_file ($_FILES [ "userfile" ][ "tmp_name" ], $uploadfile )) {
echo "Файл корректен и был успешно загружен.\n" ;
} else {
echo "Возможная атака с помощью файловой загрузки!\n" ;
}

echo "Некоторая отладочная информация:" ;
print_r ($_FILES );

print "

" ;

?>

PHP-скрипт, принимающий загруженный файл, должен реализовывать логику, необходимую для определения дальнейших действий над принятым файлом. Например, вы можете проверить переменную $_FILES["userfile"]["size"] , чтобы отсечь слишком большие или слишком маленькие файлы. Также вы можете использовать переменную $_FILES["userfile"]["type"] для исключения файлов, которые не удовлетворяют критерию касательно типа файла, однако, принимайте во внимание, что это поле полностью контролируется клиентом, используйте его только в качестве первой из серии проверок. Также вы можете использовать $_FILES["userfile"]["error"] и коды ошибок при реализации вашей логики. Независимо от того, какую модель поведения вы выбрали, вы должны удалить файл из временной папки или переместить его в другую директорию.

В случае, если при отправке формы файл выбран не был, PHP установит переменную $_FILES["userfile"]["size"] значением 0, а переменную $_FILES["userfile"]["tmp_name"] - пустой строкой. none.

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