Загрузка файлов на сервер с помощью PHP
Загрузка файлов в веб-приложениях является обычной практикой. В этой статье я расскажу, как загрузить файлы на сервер с помощью PHP.
Но в начале я бы хотел сказать пару слов о том, как же происходит загрузка файлов.
Для этого нам понадобится html форма с полем ввода типа <input type="file">. Кроме того, для передачи файлов на сервер необходимо форме установить тип multipart. Для этого в качестве параметра enctype указывается значение multipart/form-data.
После того, как на html страничке мы разместим форму с полем <input type="file"> в окне браузера отобразится поле с возможностью выбрать файл на локальном компьютере.
После того, как пользователь выберет нужный файл и нажмет кнопку «Загрузить» форма передаст данные php скрипту на сервер, который указан в action формы. Если action формы пустой, то данные будут переданы тому же файлу, на котором находится форма. Вся информация о загружаемом файле помещается в массив $ _FILES. Нам лишь остается извлечь эту информацию и переместить файл в необходимое нам место.
Прежде, чем приступить к написанию скрипта обработки multipart-формы, нужно отредактировать файл конфигурации php.ini, чтобы разрешить загрузку файлов на сервер.
Конфигурационный файл PHP php.ini имеет три параметра, связанные с загрузкой файлов на сервер:
- file_uploads = On - разрешает загрузку файлов на сервер по протоколу HTTP;
- upoad_tmp_dir = /tmp - устанавливает каталог для временного хранения загруженных файлов;
- upload_max_filesize = 2M - устанавливает максимальный объем загружаемых файлов.
Итак, создайте новый файл с именем upload.php и скопируйте в него следующий код.
<html> <head>Загрузка файлов на сервер</head> <body> <form enctype="multipart/form-data" action="" method="post"> <input type="hidden" name="MAX_FILE_SIZE" value="300000" /> <input type="file" name="uploadFile"/> <input type="submit" name="upload" value="Загрузить"/> </form> <?php print_r($_FILES); if(isset($_POST['upload'])){ $folder = 'path/to/folder/'; $uploadedFile = $folder.basename($_FILES['uploadFile']['name']); if(is_uploaded_file($_FILES['uploadFile']['tmp_name'])){ if(move_uploaded_file($_FILES['uploadFile']['tmp_name'], $uploadedFile)) { echo Файл загружен; } else { echo Во время загрузки файла произошла ошибка; } } else { echo 'Файл не загружен'; } } ?> </body> </html>
Если внимательно посмотреть на форму, то Вы увидите скрытое поле
<input type="hidden" name="MAX_FILE_SIZE" value="300000" />
Оно указывает на максимальный размер принимаемого файла в байтах. Но не следует доверять этому значения, так как оно является лишь уведомляющим и его легко можно обойти! Так что имейте это в виду!
После того как пользователь выбрал файл и нажал на кнопку «Загрузить», вся информация о файле, как упоминалось ранее, помещается в массив $ _FILES, а сам файл помещается во временный каталог на сервере, который указан в в php.ini.
Так как поле file называлось name="uploadFile", то массив $ _FILES будет содержать ассоциативный массив с ключом "uploadFile".
- $_FILES[' uploadFile ']['name'] - имя файла до его отправки на сервер, например, pict.gif;
- $_FILES[' uploadFile ']['size'] - размер принятого файла в байтах;
- $_FILES[' uploadFile ']['type'] - MIME-тип принятого файла (если браузер смог его определить), например: image/gif, image/png, image/jpeg, text/html;
- $_FILES[' uploadFile ']['tmp_name'] - содержит имя файла во временном каталоге, например: /tmp/phpV3b3qY;
- $_FILES[' uploadFile ']['error'] - Код ошибки, которая может возникнуть при загрузке файла.
После завершения работы скрипта, временный файл будет удален. Это означает, что мы должны его скопировать в другое место до завершения работы скрипта.
Итак, с алгоритмом разобрались! Теперь давайте взглянем на код.
Первым делом мы проверяем была ли нажата кнопка submit.
if(isset($_POST['upload'])) { }
Если кнопка submit была нажата, то дальше мы проверяем был ли файл загружен через HTTP POST:
if(is_uploaded_file($_FILES['uploadFile']['tmp_name'])) { Выполняем действие над файлом } else { echo 'Файл не загружен'; }
Если файл был загружен через HTTP POST, то далее мы его перемещаем из временного каталога в нужный нам каталог. Это делается при помощи функции move_uploaded_file, которая принимает два параметра: имя файла для загрузки и путь куда будет перемещен файл. В случае успешного перемещения файла, данная функция возвратит true, в противном случае –false.
if(move_uploaded_file($_FILES['uploadFile']['tmp_name'], $uploadedFile)) { echo Файл загружен; } else { echo Во время загрузки файла произошла ошибка; }
В нашем случае в качестве имени файла выступает имя временного файла на сервере - $_FILES['uploadFile']['tmp_name'], а в качестве каталога, куда будет перемещен файл – переменная $uploadedFile, которая было объявлена выше в скрипте и содержит новое место хранения файла.
$folder = 'path/to/folder/'; $uploadedFile = $folder. basename($_FILES['uploadFile']['name']);
Из своего опыта могу сказать, что хранить оригинальное название файла на сервере не стоит, поэтому его можно переименовать. Для этого сгенерируем случайное название для нашего файла и функция move_uploaded_file() переместит и переименует наш файл:
// Получаем расширение файла $file_ext = strtolower(strrchr($_FILES['uploadFile']['name'],'.')); // Генерируем случайное число $file_name = uniqid(rand(10000,99999)); // Формируем путь на сервере $uploadedFile = $folder.$file_name.$file_ext;
Ну и напоследок приведу список возможных ошибок, которые возникают во время загрузки файлов на сервер. Напоминаю, что код ошибки хранится в переменной $_FILES[' uploadFile ']['error']:
- 0- Ошибок не возникало, файл был успешно загружен на сервер.
- 1- Размер принятого файла превысил максимально допустимый размер, который задан директивой upload_max_filesize конфигурационного файла php.ini..
- 2- Размер загружаемого файла превысил значение MAX_FILE_SIZE, указанное в HTML-форме.
- 3- Загружаемый файл был получен только частично.
- 4- Файл не был загружен.
- 6- Нет временную папку.
- 7- Сбой при записи файлов на диск.
- 8- Загрузка файла остановлена.
Как видите, организовать загрузку файлов на сервер не так уж и сложно. Сложнее обеспечить необходимый уровень безопасности, так как загрузка файлов на сервер может использоваться злоумышленниками для атаки на сервер.
При помощи нашего скритпа злоумышленник сможет загружать произвольные файлы на сервер, к примеру, он сможет закачать на сервер php-скрипт, который рекурсивно сможет удалить все ваши файлы на сервере или PHP-shell, так что если вы пишите свой загрузчик файлов, то к этому делу надо подойти серьезно, ничего не упустив.
В нашем примере я не ставил перед собой такой задачи, а лишь показал Вам весь механизм загрузки файлов на сервер, но в следующей статье, я покажу, как обеспечить необходимый уровень безопасности!
На этом все! Удачи!
-
Комментарии (18)
- Сайт