Php страница из нескольких файлов. Загрузка файлов на сервер с помощью PHP. Скрипт для динамичной html формы
Наверняка, Вы часто загружали различные файлы на сайты . Например, загружали аватары на форуме , фотографии в социальных сетях, различные видеоролики на видеохостинги, просто файлы на файлообменники. И вот в этой статье Вы узнаете, как загрузить файлы на сервер в PHP . Именно через PHP в большинстве случаев это и реализуют.
Первым делом, что нужно усвоить - это то, что сама HTML-форма , в которую подставляется файл должна быть не совсем обычной, вот пример HTML-кода такой формы:
Ключевой момент здесь - это атрибут "enctype " со значением "multipart/form-data ". Без него ничего работать не будет.
", в котором мы ещё загружать файл не будем, а пройдёмся немного по различным важным моментам, которые надо обязательно учитывать, иначе может пострадать безопасность:
В результате, Вы увидите содержимое глобального двумерного массива $_FILES :
- name - имя загружаемого файла.
- type - MIME-type загружаемого файла. Это, пожалуй, самый важный параметр для обеспечения безопасности. И всегда при приёме файлов необходимо проверять MIME-type , иначе проблем не оберётесь. В следующей статье мы поговорим об этом более детально.
- tmp_name - физический путь к временному файлу. Именно в это место и помещается файл, а уже потом мы его переносим в другое место. Фактически, файл уже загружен, а нам лишь надо его переместить в нужную папку на сервере.
- error - код ошибки. Если 0 , то ошибок нет.
- size - размер загружаемого файла. Вот это тоже частоиспользуемая опция, и её также надо проверять, чтобы ограничить размер загружаемых файлов . Безусловно, самим сервером этот размер ограничен, однако, для всяких картинок, этот размер явно завышен (как правило, он 10 МБ ).
И все эти параметры присутствуют для каждого загружаемого файла (каждые из которых представляют собой массив в двумерном массиве $_FILES ).
Теперь давайте уже закончим с загрузкой файлов на сервер в PHP , и для этого напишем такой код (""):
То есть вначале мы задаём путь к загружаемому файлу на сервере. Здесь мы хотим поместить файл в директорию "images " с тем же именем, что и было раньше у файла. А функцией move_uploaded_file() мы перемещаем файл в выбранную нами директорию из его временного хранилища.
Однако, обратите внимание, это очень важно! Так использовать код ни в коем случае нельзя, иначе Вашему сайту будет угрожать серьёзная опасность! Фактически, на данный момент может быть загружено абсолютно всё, что угодно: любые исполняемые файлы, скрипты, HTML-страницы и другие весьма опасные вещи. Поэтому обязательно надо проверять загружаемые файлы на сервер очень тщательно. И вот этим мы и займёмся в следующей статье. Поскольку тема очень важная, то я советую Вам подписаться на обновления, чтобы не пропустить эту статью.
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 скрипт загрузки файлов на сервер
Загрузку нескольких файлов можно реализовать используя, например, различные значения 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. Для этого нам нужно знать, что такие загрузки происходят с помощью простой multipart-формы , у которой имеется специальное поле для загрузки файла.
В качестве параметра enctype в такой форме нужно указывать значение multipart/form-data. Отправляется методом POST.
Как обрабатывать multipart-формы на PHPПосле нажатия кнопки "Загрузать" PHP помещает файл во временную директорию и задает файлу временное имя(оно отличается от загружаемого - ниже будет видно). И сразу же создается 4 переменных глобального массива $_FILES:
- $_FILES["uploadfile"]["name"] - имя файла до его отправки на сервер (то есть оригинальное);
- $_FILES["uploadfile"]["size"] - размер принятого файла в байтах;
- $_FILES["uploadfile"]["type"] - MIME-тип принятого файла (если браузер смог его определить), например: image/gif, image/png, image/jpeg, text/html;
- $_FILES["uploadfile"]["tmp_name"] - содержит имя файла во временном каталоге, например: /tmp/php57Opq2Y;
- $_FILES["uploadfile"]["error"] - Код ошибки, которая может возникнуть при загрузке файла. Ключ ["error"] был добавлен в PHP 4.2.0.
Обратите внимание : после окончания работы скрипта загрузки файла на сервер - временный файл будет удален, поэтому необходимо скопировать этот файл из временной директории в какую-либо папку, например files при помощи функции copy() ; Не нужно применять функцию move(), так как у copy в этот момент есть 2 преимущества: временный файл самостоятельно удалиться, и если временный каталог находится на другом носителе - то выведется ошибка.
Подсказка : процесс должен начинаться по условию нажатия кнопки "Загрузить", то ест к примеру: if($_POST["submit"]){то выполняй действия}
Картинка, которая наглядно покажет 4 созданные переменные глобального массива $_FILES:
Я думаю теперь все у вас прояснилось, что куда попадает и что-где создается...и далее манипулирую этими полями, можем начать работать с этой формочкой на php
Примерно так может выглядеть сам скрипт:
if($_POST["submit"]){
@mkdir("files", 0777); // создаем папку, если ее нет то ошибки не будет, задаем права
/*echo "";
print_r($_FILES);
echo "";*/
$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"]."
";}
Вот так вот и происходит процесс загрузки файла на сервер средствами PHP.
Надеюсь было кому-либо полезно!
В этой заметке хочу осветить интересный способ загрузки файлов на сервер. Срипт, который получится полностью рабочий и после некоторой адаптации может быть использован вами, в ваших проектах, если конечно будет вам интересен.
Да этот способ можно назвать "AJAX загрузка файлов на сервер", хотя он и не использует ни ActiveXObject ни XMLHttpRequest , тем не менее это то, что в последствии превратилось в AJAX. Вообще, здесь я раскрою несколько трюков разработки, которые будут довольно неплохой находкой для начинающих.
Во первых метод использует динамически добавляемые/удаляемые поля загрузки файлов (листинг JavaScript прилагается) - т.е. в данной заметке рассматривается загрузка и обработка неопределённого множества файлов на сервер, и как всегда я стараюсь писать как можно лаконичнее и понятнее.
Во вторых, конечно всё будет происходить, именно без перезагрузки страницы .
В третьих будет дан серверный скрипт, который принимает данные, выводит информацию, и обрабатывает ошибки загрузки файлов
И в четвёртых, в конце загрузки файлов, пользователю будет выведена информация о том, какие файлы загрузились, а какие нет, и почему. В общем ценная штука в арсенале разработчика.
Как мы уже знаем, при написании html форм атрибуты "name" - элементов формы, впоследствии являются ключами глобальных массивов: $_REQUEST $_GET или $_POST и если в форме будут два поля с одинаковым атрибутом "name" то значение последнего поля "затрёт" значения предыдущих в глобальном массиве. Т.е. если у нас есть следующее:
То в обрабатывающем скрипте ма увидим массив $_FILES, котором будет только один ключ "upfile", а значение первого поля с id="one" - затрётся.
Решается такая проблема банально просто: даём разные имена атрибутам "name" и "id". Но! Что делать, если поля для загрузки файлов должны добавляться динамически, и их количество заранее не известно? Как правило программисты предпочитают генерировать подобные вещи в цикле, добавляя к атрибуту "name" некий числовой суффикс, добиваясь тем самым уникальности атрибута "name", а атрибут id за редким исключением почти всегда можно опустить (Вспоминаем методы DOM для доступа к элементам) Серверный скрипт генерации формы может иметь следующий вид: