PHP-скрипт для загрузки файлов

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

PHP-скрипт для загрузки файлов

Простая загрузка файла на сервер с помощью PHP

Вам не составит труда написать собственный PHP-скрипт для загрузки файлов на сервер. Прежде всего, необходимо создать HTML-форму с полем ввода file input. Далее привязать к ней PHP-скрипт, который переместит файл в указанную директорию. Чтобы закачать файл на сервер при помощи PHP-скрипта, выполните следующие действия:

  1. Создайте простую HTML-форму: потребуется простая форма с функциею указания файла. Она размещается в файле basic.php:
<html><head><title>Basic File Upload</title></head><body><h1>Basic File Upload</h1><form method="post" action="basic.php" enctype="multipart/form-data"><label for="inputfile">Upload File</label><input type="file" id="inputfile" name="inputfile"></br><input type="submit" value="Click To Upload"></form></body></html>

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

Важно: не забудьте добавить enctype=”multipart/form-data” в тег <form>.

PHP-скрипт для загрузки файлов
  1. Создаем PHP-скрипт для обработки формы загрузки. В PHP вся информация о загруженных файлах содержится в глобальной переменной $_FILES. То есть, используя $_FILES, можно проверить, был ли загружен файл. Если файл был загружен, то можно без проблем переместить его в нужную директорию с помощью возможности move_uploaded_file PHP:
<?phpif(isset($_FILES) && $_FILES['inputfile']['error'] == 0){ // Проверяем, загрузил ли посетитель файл$destiation_dir = dirname(__FILE__).'/'.$_FILES['inputfile']['name']; // Директория для размещения файлаmove_uploaded_file($_FILES['inputfile']['tmp_name'], $destiation_dir); // Перемещаем файл в желаемую директориюecho 'File Uploaded'; // Оповещаем посетителя об успешной загрузке файла}else{echo 'No File Uploaded'; // Оповещаем посетителя о том, что файл не был загружен}?>

Приведенный выше код проверяет, загрузил ли посетитель файл. Если файл загружен, то мы перемещаем файл в указанную директорию. В приведенном выше скрипте мы перемещаем файл в ту же папку, где находится файл basic.php.

Ниже приведена полная версия PHP move uploaded file примера:

<?phpif(isset($_FILES) && $_FILES['inputfile']['error'] == 0){ // Проверяем, загрузил ли посетитель файл$destiation_dir = dirname(__FILE__).'/'.$_FILES['inputfile']['name']; // Директория для размещения файлаmove_uploaded_file($_FILES['inputfile']['tmp_name'], $destiation_dir); // Перемещаем файл в желаемую директориюecho 'File Uploaded'; // Оповещаем посетителя об успешной загрузке файла}else{echo 'No File Uploaded'; // Оповещаем посетителя о том, что файл не был загружен}?><html><head><title>Basic File Upload</title></head><body><h1>Basic File Upload</h1><form method="post" action="basic.php" enctype="multipart/form-data"><label for="inputfile">Upload File</label><input type="file" id="inputfile" name="inputfile"></br><input type="submit" value="Click To Upload"></form></body></html>

Пожалуйста, не тестируйте этот PHP move uploaded file пример на сервере. Он не отвечает требованиям безопасности, и был создан специально для того, чтобы наглядно показать, как загружать файлы при помощи PHP.

Вопрос: Почему приведенный выше скрипт небезопасен? Ответ: При помощи скрипта, приведенного выше, можно загрузить файл любого типа на сервер. То есть, если вы используете скрипт в таком виде на “живом” сервере, то любой хакер сможет загрузить собственные PHP-скрипты, и взломать веб-сайт и сервер.

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

Что такое $_FILES?

$_FILES – это глобальная переменная в PHP наподобие $_POST или $_GET. Она представляет собой ассоциативный массив, в котором находится информация о загруженном файле при помощи способа HTTP POST.

То есть, если выполнить print_r($_FILES) для приведенного выше скрипта, то мы получим следующую информацию:

Array( [inputfile] => Array( [name] => upload-file-php.jpg      [type] => image/jpeg            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpcQiYhh            [error] => 0            [size] => 6887  ))

То есть, для каждого поля ввода <input type=”file” name=”inputfile“/> в массиве создается элемент. Если вы создадите <input type=”file” name=”test”>, то название элемента также будет изменено на test . Например:

Array(    [test] => Array        (            [name] => upload-file-php.jpg            [type] => image/jpeg            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpcQiYhh            [error] => 0            [size] => 6887        ))

Сейчас для каждого input file , перемещаемого при помощи move uploaded file PHP , создается пять элементов (name, type, tmp_name, error, size). Давайте познакомимся с данными элементами поближе:

  1. name: включает название загруженного посетителем файла. Если вы загрузите файл abc.txt в браузер, то элемент name получит название abc.txt ;
  2. type: тип загруженного файла или mime-type , если точнее. Для файла JPG этот элемент будет иметь значение image/jpeg . Если загрузить текст, то элемент получит значение text/plain . Для различных типов файлов различным будет и mime-type . Ниже приведены самые распространенные mime-типы :
  • JPEG: image/jpeg ;
  • PNG: image/png ;
  • Текст: text/plain ;
  • Word: application/msword .
  1. tmp_name: временное расположение для загруженного файла. Этот путь можно без труда настроить в переменной upload_tmp_dir , указанной в файле php.ini .
  1. error: информация об ошибке. Содержит тип ошибки, возникшей в процессе загрузки. Например, когда размер файла превышает максимальный или когда не был указан файл для загрузки. Для любой возникшей ошибки имеется числовое значение и константа. Ниже приведен полный список ошибок, которые могут возникнуть в PHP move uploaded file примере :
  • UPLOAD_ERR_OK (значение 0) . Означает, что файл был успешно загружен без ошибок;
  • UPLOAD_ERR_INI_SIZE (значение 1) . Размер файла превышает указанный в переменной upload_max_filesize в файле php.ini ;
  • UPLOAD_ERR_FORM_SIZE (значение 2) . Размер файла превышает установленное в переменной формы MAX_FILE_SIZE значение;
  • UPLOAD_ERR_PARTIAL (значение 3) . Файл загружен не в полном объеме;
  • UPLOAD_ERR_NO_FILE (значение 4) . Отсутствует файл для загрузки;
  • UPLOAD_ERR_NO_TMP_DIR (значение 6) . Указанной директории для временного хранения не существует;
  • UPLOAD_ERR_CANT_WRITE (значение 7) . Невозможно записать файл на диск.
  1. size: размер загруженного файла в байтах.

Что такое move_uploaded_file?

move_uploaded_file представляет собой возможность, которая перемещает загруженный файл из временной директории в папку назначения. Перед перемещением move_uploaded_file PHP проверяет, был ли загружен файл, указанный в HTTP-методе post .

Если файл был успешно перемещен, то вы получите ответ true или false . В первом примере мы использовали следующую строку кода:

move_uploaded_file($_FILES['inputfile']['tmp_name'], $destiation_dir )

А сейчас давайте сделаем красиво, и выведем информацию:

if(move_uploaded_file($_FILES['inputfile']['tmp_name'], $destiation_dir )){echo "File Uploaded"}else{echo "File Not uploaded"}

Изменяем лимит размера загружаемого файла

У каждой формы для загрузки файлов должен быть установлен лимит размера, иначе посетители станут загружать увесистые файлы. Выставить ограничение на move uploaded file PHP можно легко двумя методами:

  • В файле PHP.ini есть специальная переменная upload_max_filesize , которая отвечает за максимальный размер загружаемых файлов. Далее приведена строчка из php.ini , которая ограничивает размер загружаемых файлов до 20 Мб: upload_max_filesize = 20M .
  • Если загружаемый файл будет иметь больший размер, то посетитель получит ошибку UPLOAD_ERR_INI_SIZE или значение «2» в переменной $_FILES . Важно учесть, что значение переменной upload_max_filesize не должно превышать значение переменной post_max_size , указанной в php.ini ;
  • Ограничить размер загружаемого файла можно легко, поместив скрытый элемент ввода с названием UPLOAD_ERR_INI_SIZE в форму загрузки. Сделать это можно так: <input type=»hidden» name=»MAX_FILE_SIZE» value=»50000″ />.

Если необходимо сильно увеличить filesize , то не забудьте настроить время исполнения php-скриптов .

Как обезопасить PHP-скрипт загрузки файлов

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

В виде примера сделаем так, чтобы посетители не могли загружать jpeg-файлы размером свыше 1 Мб. Установите соответствующее ограничение в переменной upload_max_filesize файла php.ini . Ниже приведена улучшенная версия скрипта:

<?phpini_set('upload_max_filesize', '1M'); //ограничение в 1 мбif ($_SERVER['REQUEST_METHOD'] == "POST" ) {if ($_FILES['inputfile']['error'] == UPLOAD_ERR_OK && $_FILES['inputfile']['type'] == 'image/jpeg') { //проверка на наличие ошибок$destiation_dir = dirname(__FILE__) . '/' . $_FILES['inputfile']['name']; // директория для размещения файлаif (move_uploaded_file($_FILES['inputfile']['tmp_name'], $destiation_dir)) { //перемещение в желаемую директориюecho 'File Uploaded'; //оповещаем посетителя об успешной загрузке файла} else {echo 'File not uploaded';}} else {switch ($_FILES['inputfile']['error']) {case UPLOAD_ERR_FORM_SIZE:case UPLOAD_ERR_INI_SIZE:echo 'File Size exceed';brake;case UPLOAD_ERR_NO_FILE:echo 'FIle Not selected';break;default:echo 'Something is wrong';}}}?><html><head><title>Secure File Upload</title></head><body><h1>Secure File Upload</h1><form method="post" action="secure.php" enctype="multipart/form-data"><label for="inputfile">Upload File</label><input type="file" id="inputfile" name="inputfile"></br><input type="submit" value="Click To Upload"></form></body></html>

Мультизагрузка файлов с помощью PHP-скрипта

Можно загружать сразу же пару файлов с помощью $_FILES и move_uploaded_file PHP . Ниже я расскажу вам о двух методах мультизагрузки файлов при помощи PHP-скрипта :

  1. Используя различные имена Input .
  2. Используя одно и то же имя input, но с привлечением массива.

1. Используя различные имена Input:

Можно загружать сразу же пару файлов, используя пару элементов ввода. Как говорилось ранее, если мы создаем пару элементов input, то в $_FILES будет создано пару основных элементов. К примеру, для приведенной ниже формы:

<input type="file" id="profilepic" name="profilepic"><input type="file" id="resume" name="resume">

$_FILES представит массив следующего содержания:

Array(    [profilepic] => Array        (            [name] => 20141002_094257.jpg            [type] => image/jpeg            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpoBWrBZ            [error] => 0            [size] => 2669096        )    [resume] => Array        (            [name] => 20141002_094247.jpg            [type] => image/jpeg            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpjwUmVZ            [error] => 0            [size] => 2207657        ))

Приведенный ниже PHP move uploaded file пример необходимо писать с учетом того, что один элемент предназначен для аватарки (изображение), а другой – для загрузки резюме (файла в формате .doc ):

<?phpif ($_SERVER['REQUEST_METHOD'] == "POST" ) {if ($_FILES['profilepic']['error'] == UPLOAD_ERR_OK && $_FILES['profilepic']['type'] == 'image/jpeg') { // Проверяем на наличие ошибок$destiation_dir = dirname(__FILE__) . '/' . $_FILES['profilepic']['name']; // Директория для размещения файлаif (move_uploaded_file($_FILES['profilepic']['tmp_name'], $destiation_dir)) { // Перемещаем файл в желаемую директориюecho 'Profile Pic Uploaded'; // Оповещаем посетителя об успешной загрузке файла} else {echo 'Profile Pic not uploaded';}} else {switch ($_FILES['profilepic']['error']) {case UPLOAD_ERR_FORM_SIZE:case UPLOAD_ERR_INI_SIZE:echo 'Profile Pic Size exceed';brake;case UPLOAD_ERR_NO_FILE:echo 'Profile Pic Not selected';break;default:echo 'Something is wrong with Profile PIC';}}if ($_FILES['resume']['error'] == UPLOAD_ERR_OK && $_FILES['resume']['type'] == ' application/msword') { // Проверяем на наличие ошибок$destiation_dir = dirname(__FILE__) . '/' . $_FILES['resume']['name']; // Директория для размещения файлаif (move_uploaded_file($_FILES['resume']['tmp_name'], $destiation_dir)) { // Перемещаем файл в желаемую директориюecho 'resume Uploaded'; // Оповещаем посетителя об успешной загрузке файла} else {echo 'resume not uploaded';}} else {switch ($_FILES['resume']['error']) {case UPLOAD_ERR_FORM_SIZE:case UPLOAD_ERR_INI_SIZE:echo 'resume Size exceed';brake;case UPLOAD_ERR_NO_FILE:echo 'resume Not selected';break;default:echo 'Something is wrong with resume';}}}?><html><head><title>Multiple File Upload</title></head><body><h1>Multiple File Upload</h1><form method="post" action="multiple.php" enctype="multipart/form-data"><label for="profilepic">Profile Pic</label><input type="file" id="profilepic" name="profilepic"></br><label for="resume">Resume</label><input type="file" id="resume" name="resume"></br><input type="submit" value="Click To Upload"></form></body></html>

2. Используем одно поле ввода input, но с применением массива:

Как и в случае с иными типами input , для move uploaded file PHP мы можем использовать массив с input type , указанным в php . То есть:

<input type="file" id="pic" name="pic[]"><input type="file" id="pic" name="pic[]"><input type="file" id="pic" name="pic[]">

То есть, для приведенного выше HTML , $_FILES предоставит данные со следующей структурой:

Array(    [pic] => Array        (            [name] => Array                (                    [0] => upload-file-php.jpg                    [1] => variable-scope-php.jpg                    [2] => magic-constants.jpg                )            [type] => Array                (                    [0] => image/jpeg                    [1] => image/jpeg                    [2] => image/jpeg                )            [tmp_name] => Array                (                    [0] => /Applications/XAMPP/xamppfiles/temp/phpML5kOy                    [1] => /Applications/XAMPP/xamppfiles/temp/phpNZbuw7                    [2] => /Applications/XAMPP/xamppfiles/temp/phpO8VFAk                )            [error] => Array                (                    [0] => 0                    [1] => 0                    [2] => 0                )            [size] => Array                (                    [0] => 6887                    [1] => 8036                    [2] => 9967                )        ))

Скачать код, использованный в статье

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *