- PHP и загрузка файлов
- Элементарное решение
- В чем заключается проблема
- О глобальной переменной
- Элементы для input files
- Функция перемещения – кратко о главном
- Корректировка лимитов размеров
- Вопрос безопасности
- Мультизагрузка
- Готов к работе или требует доработки
- Проверьте размер файла перед загрузкой
- Отмена загрузки на стороне клиента
- Отмена загрузки на стороне сервера
- Проверка PHP
PHP и загрузка файлов
Загрузка документов и файлов на сайт для рядового пользователя – весьма распространенная задача. С ней сталкивался чуть ли не каждый. Реализуется через специальную форму. Подобные операции преследуют юзера повсеместно: в социальных сетях, на видео-хостингах, а также в виде файлообменников. Но для разработчика подобные манипуляции выглядят несколько иначе.
Данная статья расскажет о том, как на PHP загрузить файлы на сервер. Именно такой подход чаще всего реализован на веб-ресурсах.
Элементарное решение
PHP скрипт для заливания файла на сервер создать способен каждый. Справиться с поставленной задачей удается несколькими способами. Форма может быть «простой» или «сложной».
Первый вариант предусматривает создание такого «окна»:
Basic File Upload
Это – HTML, в котором находится поле file input. Для того, чтобы файл можно было загрузить на сервер через PHP, потребуется выполнить такие действия:
- Создать форму «заливания». Код можно скопировать выше.
- Разместить полученный HTML в basic.php.
- Добавить строчку в тег «enctype=”multipart/form-data».
- Создать скрипт формы загрузки. Речь идет о PHP Script. Для этого потребуется $_FILES. Начать с формы, которая будет проверять, загрузил ли юзер документ.
- Создать полный скрипт для заливания документации на сервер, используя PHP move uploaded file.
Теперь скрипт должен работать. Не рекомендуется использовать его на собственном сервере. Исключение – если он тоже «тестовый». Это – лишь наглядный пример того, как через PHP и его функции можно скачивать документы и заливать их на серверы.
В чем заключается проблема
Представленные выше кодификации – это лишь шаблоны, на которые можно опираться при изучении принципов загрузки файлов через скрипты. Они не отвечают установленным принципам безопасности, поэтому подходят только в виде примеров.
Предложенные ранее коды помогают загружать файл любого типа на server. Это значит, что каждый хакер сможет при желании запустить собственные PHP-скрипты, чтобы позже осуществить взлом сайта. Это определенные риски. Поэтому необходимо защищать собственные servers после создания формы «заливания» документации.
О глобальной переменной
$_FILES – элемент, который успешно используется для поставленной изначально задачи. Разобравшись с ним, можно успешно проверить факт загрузки файла на сервер сайта.
$_FILES – глобальная переменная PHP, которая напоминает $_POST и $_GET. Это – ассоциативный массив, в котором располагается информация о загруженном документе. Для этого применяется method 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 file, система создаст для перемещаемых через move uploaded file PHP несколько элементов. Их стоит рассмотреть поближе.
Элементы для input files
Когда на сервер загружаются файлы, для них создаются несколько файлов:
Каждый предусматривает собственные особенности, о которых должен знать разработчик. Рекомендуется запомнить следующие сведения:
- Name отвечает за название загруженного юзером файла. Включает в себя также формат документации.
- Type – тип загруженного файла или mime-type. При загрузке текста получается значение text/plain, картинки – image/jpeg или /png. Каждый тип файла имеет собственный mime-тип.
- Tmp_name – место временного хранения загруженного документа. Пусть подлежит возможности корректировки. Делается это путем изменения в переменной upload_tmp_dir. Обнаружить ее можно в файле php. Ini.
- Error. Отвечает за информацию об ошибке. Указывает на ее тип. Отображает сбои, возникающие при попытке загрузки документации. Пример – размер файла превышает максимально допустимый. Каждая error имеет собственный код – числовое значение и константу.
В случае с size все просто – это размер документа, который нужно залить на сервер PHP. Параметр указывается в байтах.
А что там про ошибки
Проверка на errors – важный момент всей операции. Если в процессе заливания файла на server возникли неполадки, документ может вовсе не появиться на сайте. Вот несколько самых распространенных «сбоев», которые могут быть выведены на экран:
- Upload_err_form_size (значение 2) – размер документа превышает установленное в переменной формы max_file_size значение.
- Ini_size (значение 1) – размер больше, чем предусматривает переменная upload_max_filesize в php.imi.
- Err_ok (значение 0) – успешная загрузка файла. Ошибок в процессе не обнаружено.
- _partial (значение 3) – неполная загрузка файла.
- No_file (значение 4) – документ для скачивания на сервер отсутствует.
- No_tmp_dir (значение 6) – указанной директории для временного хранения файла не обнаружено.
- Cant_write (значение 7) – записать файл на диск невозможно.
Этого новичкам будет достаточно в плане изучения ошибок. Но для полноценного заливания документации на server предстоит выучить одну полезную функцию.
Функция перемещения – кратко о главном
Move_uploaded_file – это функция, которая отвечает за перемещение загруженного файла из временной директории в ту или иную папку. Перед этим PHP будет проверять, был ли загружен документ в HTTP-методе post.
If файл перемещен без ошибок, на экране можно будет увидеть true или false. Предложенный ранее пример имел следующую строку:
Ее можно представить более красиво:
if(move_uploaded_file($_FILES['inputfile']['tmp_name'], $destiation_dir )) < echo "File Uploaded" >else
Как и ранее, данный вариант выступает лишь наглядным шаблоном.
Корректировка лимитов размеров
Размер загружаемого файла – параметр, который можно менять. Без него обойтись проблематично. Он обязателен для того, чтобы форма загрузки файла в PHP работала корректно и ограничивала юзеров. Иначе можно столкнуться с быстрой перегрузкой сервера – посетители будут заливать весьма увесистые документы.
Ограничения могут быть выставлены несколькими способами:
- В файле php.ini хранится переменная uload_max_filesize. Она отвечает за предельный размер заливаемых документов. Через знак равенства в соответствующем файле требуется указать интересующую характеристику.
- Ограничение устанавливается за счет помещения скрытого элемента ввода под названием upload_err_ini_size в форму загрузки. Пример – прописать .
- Если загружаемый файл больше, пользователь увидит «значение «2» в переменной $_FILES. Стоит обратить внимание на то, что upload_max_filesize не должен быть больше переменной post_max_size в php.ini.
Для того, чтобы откорректировать filesize в большую сторону на значимое значение, нужно просто изменить время исполнения php-скрипта.
Вопрос безопасности
Ранее было сказано о том, что предложенный пример кода на PHP не соответствует параметрам безопасности. Защищать загрузчик нужно каждому разработчику.
Далее для работы используем jpeg-документы размером более 1 МБ. Скачать их на сервер не получится, если выставить соответствующие ограничения. Они прописываются в переменной upload_max_filesize документа php.ini.
Выше представленный код form action предусматривает упомянутое ранее ограничение. За счет него получится настраивать принципы работы загрузчика.
Мультизагрузка
PHP-скрипты позволяют осуществлять мультизагрузку. Ее можно реализовать несколькими способами:
- Через имя файла input. Соответствующие «названия» должны быть разными.
- Привлекая массив. В этой ситуации input могут иметь одни и те же имена.
Все зависит от личных предпочтений разработчика. Первый вариант позволяет загружать несколько документов через элементы ввода. Если создается то или иное количество элементов input, в $_FILES создаются определенные «ключевые» компоненты. Вот наглядный пример:
$_FILES будет выглядеть массивом:
А вот PHP move uploaded file, при помощи которого файл загрузится на сервер. Здесь нужно учитывать, что один элемент предназначается для авы (картинка), другой – для резюме (файл в формате .doc).
А теперь стоит рассмотреть второй вариант – с одним полем input, но с массивами. Для uploaded file PHP можно задействовать массив с input type, прописанным в php:
Для ранее рассмотренного HTML $_Files будет обладать такую структуру:
Готов к работе или требует доработки
Коды, рассмотренные в примере – это шаблоны. Они готовы к работе, хоть и примитивны. Для нормального функционирования оные требуют расширения:
- удаления символов и пробелов из названия;
- занесения информации в БД для дальнейшей обработки;
- проверки размера файлов;
- сжатия изображений и картинок.
Теперь понятно, что собой представляет php _files tmp_name и как создавать формы для загрузки документации на серверы. А чтобы такие слова как server, value и submit не вызывали лишних вопросов, рекомендуется пройти курсы по PHP и серверной работы. Дистанционные занятия с выдачей сертификата в конце обучения – лучший способ быстро освоиться в любой сфере разработки программного обеспечения.
Проверьте размер файла перед загрузкой
Я использую этот javascript, который я получил отсюда, и он отлично работает для того, что мне нужно.
var _validFileExtensions = [".jpg", ".jpeg"]; function File_Validator(theForm) < var arrInputs = theForm.getElementsByTagName("input"); for (var i = 0; i < arrInputs.length; i++) < var oInput = arrInputs[i]; if (oInput.type == "file") < var sFileName = oInput.value; var blnValid = false; for (var j = 0; j < _validFileExtensions.length; j++) < var sCurExtension = _validFileExtensions[j]; if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) < blnValid = true; break; >> if (!blnValid) < alert("Invalid image file type!"); return false; >> > return true; >
Теперь мне было интересно, может ли, кроме того, проверить размер файла и сбой, если файл больше 500kb -> все, прежде чем нажимать кнопку отправки / отправки?
После изучения того, что предложил PHPMyCoder, я в конечном итоге решаю, используя этот код javascript:
Это проверяет размер файла и предупреждает пользователя перед отправкой формы.
Отмена загрузки на стороне клиента
В современных браузерах (FF> = 3.6, Chrome> = 19.0, Opera> = 12.0 и ошибках в Safari) вы можете использовать API файлов HTML5 . Когда значение входного файла изменяется, этот API позволит вам проверить, соответствует ли размер файла вашим требованиям. Конечно, это, как и MAX_FILE_SIZE , может быть изменено, поэтому всегда используйте проверку на стороне сервера.
Отмена загрузки на стороне сервера
На стороне сервера невозможно остановить загрузку из PHP, поскольку после того, как PHP был вызван, загрузка уже завершена. Если вы пытаетесь сохранить пропускную способность, вы можете запретить загрузку со стороны сервера с настройкой ini upload_max_filesize . Проблема с этим заключается в том, что это относится ко всем загрузкам, поэтому вам придется выбирать что-то либеральное, которое работает для всех ваших загрузок. Использование MAX_FILE_SIZE обсуждалось в других ответах. Я предлагаю прочитать руководство по нему . Знайте, что это, как и любая другая клиентская сторона (включая проверку javascript), могут быть изменены, поэтому вы должны всегда иметь проверку на стороне сервера (PHP).
Проверка PHP
На стороне сервера вы должны проверить, что файл находится в пределах ограничений по размеру (потому что все до этой точки, за исключением установки INI, можно подделать). Вы можете использовать массив $_FILES чтобы узнать размер загрузки. (Документы о содержимом $_FILES можно найти ниже документов MAX_FILE_SIZE )
Я создал jQuery версию ответа PhpMyCoder:
$('form').submit(function( e ) < if(!($('#file')[0].files[0].size < 10485760 && get_extension($('#file').val()) == 'jpg')) < // 10 MB (this size is in bytes) //Prevent default and display error alert("File is wrong type or over 10Mb in size!"); e.preventDefault(); >>); function get_extension(filename)
JavaScript, работающий в браузере, обычно не имеет доступа к локальной файловой системе. Это вне песочницы. Поэтому я думаю, что ответ отрицательный.