Файл PHP не загружается на сервер

Обновлено: 02.07.2024

В этом руководстве вы узнаете, как загрузить файл на удаленный веб-сервер с помощью PHP.

Загрузка файлов с помощью PHP

В этом уроке мы узнаем, как загружать файлы на удаленный сервер, используя простую HTML-форму и PHP. Вы можете загружать любые файлы, например изображения, видео, ZIP-файлы, документы Microsoft Office, PDF-файлы, а также исполняемые файлы и множество других типов файлов.

Шаг 1. Создание HTML-формы для загрузки файла

В следующем примере создается простая HTML-форма, которую можно использовать для загрузки файлов.

Пример

Примечание. В дополнение к полю выбора файла форма загрузки должна использовать метод публикации HTTP и должна содержать атрибут enctype="multipart/form-data". Этот атрибут гарантирует, что данные формы кодируются как составные данные MIME, что требуется для загрузки больших объемов двоичных данных, таких как изображения, аудио, видео и т. д.

Шаг 2. Обработка загруженного файла

Вот полный код нашего файла "upload-manager.php". Он будет хранить загруженный файл в папке «загрузка» на постоянной основе, а также выполнять некоторые базовые проверки безопасности, такие как тип файла и размер файла, чтобы гарантировать, что пользователи загружают файл правильного типа и в допустимых пределах.

Пример

Примечание. Приведенный выше сценарий предотвращает загрузку файла с тем же именем, что и у существующего файла в той же папке. Однако, если вы хотите разрешить это, просто добавьте к имени файла случайную строку или отметку времени, например $filename = time() . '_' . $_FILES["фото"]["имя"];

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

Объяснение кода

После отправки формы информация о загруженном файле может быть доступна через суперглобальный массив PHP с именем $_FILES . Например, наша форма загрузки содержит поле выбора файла с именем photo (т. е. name="photo"), если какой-либо пользователь загрузил файл с помощью этого поля, мы можем получить его данные, такие как имя, тип, размер, временное имя или любую ошибку. произошло при попытке загрузки через ассоциативный массив $_FILES["photo"], например:

  • $_FILES["photo"]["name"] — это значение массива указывает исходное имя файла, включая расширение файла. Он не включает путь к файлу.
  • $_FILES["photo"]["type"] – это значение массива указывает тип файла MIME.
  • $_FILES["photo"]["size"] — это значение массива указывает размер файла в байтах.
  • $_FILES["photo"]["tmp_name"] – это значение массива указывает временное имя, включая полный путь, который назначается файлу после его загрузки на сервер.
  • $_FILES["photo"]["error"] — значение этого массива указывает код ошибки или состояния, связанный с загрузкой файла, например. будет 0, если ошибки нет.

Код PHP в следующем примере просто отображает сведения о загруженном файле и сохраняет его во временном каталоге на веб-сервере.

Пример

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

Вам лучше тщательно проверить структуру и значения $_FILES.
Следующий код абсолютно не может вызвать никаких ошибок.

Пример:
('Content-Type: text/plain; charset=utf-8');

// Не определено | Несколько файлов | $_FILES Corruption Attack
// Если этот запрос подпадает под любой из них, считать его недействительным.
if (
!isset( $_FILES [ 'upfile' ][ 'error' ]) ||
is_array ( $_FILES [ 'upfile' ][ 'error' ])
) выдать новое исключение RuntimeException ("Недопустимые параметры");
>

// Проверяем значение $_FILES['upfile']['error'].
switch ( $_FILES [ 'upfile' ][ 'error' ]) case UPLOAD_ERR_OK :
break;
case UPLOAD_ERR_NO_FILE :
сгенерировать новое исключение RuntimeException ('Файл не отправлен');
случай UPLOAD_ERR_INI_SIZE :
случай UPLOAD_ERR_FORM_SIZE :
генерировать новое исключение RuntimeException («Превышено ограничение на размер файла»);
по умолчанию:
генерировать новое исключение RuntimeException ('Неизвестные ошибки');
>

// Здесь также следует проверить размер файла.
if ( $_FILES [ 'upfile' ][ 'size' ] > 1000000 ) выдать новое исключение RuntimeException («Превышено ограничение на размер файла»);
>

// НЕ ДОВЕРЯТЬ $_FILES['upfile']['mime'] VALUE !!
// Проверьте MIME Type самостоятельно.
$finfo = новая информация ( FILEINFO_MIME_TYPE );
if ( false === $ext = array_search (
$finfo -> file ( $_FILES [ 'upfile' ][ 'tmp_name' ]),
array(
' jpg' => 'изображение/jpeg',
'png' => 'изображение/png',
'gif' => 'изображение/gif',
),
true
)) throw new RuntimeException ('Недопустимый формат файла.');
>

// Вы должны назвать его уникальным.
// НЕ ИСПОЛЬЗУЙТЕ $_FILES['upfile']['name'] БЕЗ КАКОЙ-ЛИБО ПРОВЕРКИ!!
// В этом примере получаем уникальное имя сейфа из его бинарных данных.
if (! move_uploaded_file (
$_FILES [ 'upfile' ][ 'tmp_name' ],
sprintf ( './uploads/%s.%s' ,
sha1_file ( $_FILES [ 'upfile' ][ 'tmp_name' ]),
$ext
)
)) throw new RuntimeException ("Не удалось переместить загруженный файл.');
>

echo 'Файл успешно загружен.' ;

> поймать ( RuntimeException $e )

echo $e -> getMessage();

Пояснение к скрытому полю формы MAX_FILE_SIZE:

В PHP есть несколько странная функция проверки нескольких "максимальных размеров файла".

Двумя широко известными ограничениями являются параметры php.ini "post_max_size" и "upload_max_size", которые в сочетании накладывают жесткое ограничение на максимальный объем данных, который может быть получен.

Вдобавок к этому в PHP каким-то образом была реализована функция мягкого лимита. Он проверяет наличие имени поля формы «max_file_size» (верхний регистр также допустим), которое должно содержать целое число с максимально допустимым количеством байтов. Если загруженный файл больше, чем целое число в этом поле, PHP запрещает эту загрузку и представляет код ошибки в массиве $_FILES-Array.

Внимание: *НЕ* доверяйте $_FILES['userfile']['type'] проверке типа загруженного файла; если вы это сделаете, ваш сервер может быть скомпрометирован. Я покажу вам ниже, почему:

В руководстве (если вы прокрутите выше) указано: $_FILES['userfile']['type'] — MIME-тип файла, если браузер предоставил эту информацию. Примером может быть "изображение/gif".

Напоминаем, что этот MIME-тип можно легко подделать, так как PHP не очень далеко проверяет, действительно ли это то, что сообщил конечный пользователь!

Итак, кто-то может загрузить неприятный скрипт .php как "изображение/gif" и выполнить URL-адрес "изображения".

Мне лучше всего проверить расширение файла и использовать exif_imagetype() для проверки допустимых изображений. Многие люди предлагали использовать getimagesize(), который возвращает массив, если файл действительно является изображением, и false в противном случае, но exif_imagetype() намного быстрее. (в инструкции так написано)

IE на Mac немного проблематичен. Если вы загружаете файл с неизвестным файловым суффиксом, IE загружает файл с MIME-типом «application/x-macbinary». Результирующий файл включает в себя вилку ресурсов, обернутую вокруг файла. Не очень полезно.

Следующий код предполагает, что тип mime находится в $type и что вы загрузили содержимое файла в $content. Если файл имеет формат MacBinary, он копается в заголовке ответвления ресурса, получает длину ответвления данных (байты 83–86) и использует ее, чтобы избавиться от ответвления ресурса.

(Возможно, есть лучший способ сделать это, но это решило мою проблему):

if ($type == 'application/x-macbinary') <
if (strlen ($content) 128) die('Файл слишком мал');
$length = 0 ;
for ($i = 83; $i 86; $i ++) <
$length = ($length * 256) + ord (substr ($content, $i, 1));
>
$content = substr ($content, 128, $length);
>
?>

Из руководства:

Если в вашей форме для загрузки не выбран ни один файл, PHP вернет $_FILES['userfile']['size'] как 0, а $_FILES['userfile']['tmp_name'] — как нет.

Начиная с PHP 4.2.0, "none" больше не является надежным показателем того, что файл не загружен. Это задокументировано, если вы нажмете ссылку «коды ошибок», но вам нужно посмотреть на $_FILES['your_file']['error']. Если 4, то файл не выбран.

Если "большие файлы" (например, 50 или 100 МБ) не работают, проверьте следующее:

Может случиться так, что ваше исходящее соединение с сервером медленное, и может истечь не "время выполнения", а "время ввода", которое, например, в нашей системе по умолчанию равно 60 с. В нашем случае большая загрузка может занять 1 или 2 часа.

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

1) Вы можете просмотреть эти записи ini:

* session.gc_maxlifetime
* max_input_time
* max_execution_time
* upload_max_filesize
* post_max_size

2) Все еще не получается? Осторожно, не все можно изменить из самого скрипта. ini_set() может не переопределить.

Вместо этого используйте .htaccess.

3) Все еще не удается?. Просто убедитесь, что вы включили «.htaccess», чтобы перезаписать настройки php. Это сделано в файле apache. Вам нужны как минимум параметры AllowOverride.

Вы обязательно разрешите это вручную, если ваши основные файлы поставляются с параметром AllowOverride None.

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

Это работает для меня, для загрузки 100 МБ, продолжительностью 2 часа:

В .htaccess:
------------------------------------------------------ --------------------
сессия php_value.gc_maxlifetime 10800
php_value max_input_time 10800
php_value max_execution_time 10800
php_value upload_max_filesize 110M
php_value post_max_size 120M
---------------- ----------------------------------------------------------

В этом примере
- Поскольку я продержался от 1 до 2 часов, я разрешаю 3 часа (3600x3)
- Поскольку мне нужно 100 МБ, я разрешаю воздух выше для файла (110 МБ) и немного больше на весь пост (120M).

Для тех из вас, кто пытается заставить работать загрузку с IIS на Windows XP/2000/XP Media и т.п., вот краткое задание.

1) После того, как вы создали подкаталоги «uploads/» в том же каталоге, где работает ваш код, используйте код из oporocala выше и убедитесь, что файл, который вы пытаетесь исправить, записан в этой папке. (Я рекомендую распечатать его с помощью echo $uploadfile;)

2) В проводнике Windows перейдите в каталог загрузки, созданный выше, и поделитесь им. Для этого выполните следующие подшаги.
a) Щелкните правой кнопкой мыши папку, выберите «Общий доступ и безопасность».
b) Установите флажок «Общий доступ к этой папке в сети»
c) Установите флажок «Разрешить пользователям сети изменять мои файлы» ( ЭТО ЭТАП ОЧЕНЬ ВАЖЕН )
d) нажмите «ОК» или «Применить»

3) затем вы можете перейти в IIS, чтобы установить для него разрешения на чтение и запись. Для этого выполните следующие подшаги.
a) Откройте IIS (Пуск/Панель управления (классический вид)/Инструменты администрирования/Информационная служба Интернета
b) Перейдите в свою папку (ту, которую мы создали выше)
c) щелкните правой кнопкой мыши и выберите свойства.
г) на вкладке "Каталог" убедитесь, что установлены флажки ЧТЕНИЕ, ЗАПИСЬ И ПРОСМОТР КАТАЛОГА.
e) Для любителей безопасности: вам также следует убедиться, что для «разрешения на выполнение» установлено значение «Только сценарий» или ниже (НЕ УСТАНАВЛИВАЙТЕ НА «сценарий и исполняемый файл)» (это потому, что кто-то может загрузить сценарий в свой каталог и запустите его. И, мальчик, вы не хотите, чтобы это произошло).

Отправьте мне отзыв, сработало ли это для вас или нет, чтобы я мог обновить задачу.

PS: БОЛЬШОЕ спасибо portocala

Использование /var/www/uploads в примере кода просто преступно, имншо.

Нельзя *НЕ* загружать ненадежные файлы в ваше веб-дерево на любом сервере.

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

Файл $_FILES['userfile']['type'] практически БЕСПОЛЕЗЕН.
A. Браузеры не являются согласованными в своих MIME-типах, поэтому вы никогда не поймаете все возможные комбинации типов для любого заданного формата файла.
B. Его можно подделать, так что в любом случае это дерьмовая безопасность.

Код должен ПРОВЕРЯТЬ фактический файл, чтобы убедиться, что он выглядит кошерным.

Например, изображения можно быстро и легко запустить с помощью imagegetsize, и вы, по крайней мере, знаете, что первые N байтов ВЫГЛЯДЯТ как изображение. Это не гарантирует, что это допустимый образ, но значительно снижает вероятность того, что он будет работоспособным файлом, нарушающим безопасность.

Для серверов на основе Un*x можно использовать команду exec и 'file', чтобы узнать, считает ли операционная система, что внутреннее содержимое соответствует ожидаемому типу данных.

В прошлом у меня были проблемы с чтением файла '/tmp' при загрузке файла. Было бы неплохо, если бы PHP позволил мне прочитать этот файл ДО того, как я попытался выполнить для него move_uploaded_file, но PHP этого не сделает, по-видимому, исходя из предположения, что я буду делать что-то опасное, чтобы прочитать ненадежный файл. Отлично. Нужно переместить загруженный файл в какой-нибудь промежуточный каталог. Затем вы проверяете его содержимое как можно тщательнее. ТОГДА, если это кажется кошерным, переместите его в каталог за пределами вашего веб-дерева. Любой доступ к этому файлу должен осуществляться через PHP-скрипт, который читает файл. Помещать его в ваше веб-дерево, даже со всеми возможными проверками, слишком опасно, имншо.

Здесь много примечаний пользователей с наивными (плохими) советами. Будьте осторожны.

Небольшое замечание: есть проблема с Apache, скрытым полем формы MAX_FILE_SIZE и параметром zlib.output_compression = On. Кажется, что браузер продолжает публиковать весь файл, хотя PHP правильно выдает ошибку MAX_FILE_SIZE. Отключение сжатия zlib, кажется, решает проблему. У меня нет времени копаться и выяснять, кто виноват, но хотелось избавить других от необходимости биться головой об этом.

Также столкнулся с проблемой max_file_size, в частности, без ответа, без каких-либо ошибок при загрузке файла, размер которого превышает установленное значение upload_max_filesize.

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

Надеюсь, это кому-нибудь поможет.

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

CharsetDisable On

Небольшой фрагмент кода, который возвращает размер файла в более разборчивом формате.

функция display_filesize ( $filesize )

if( is_numeric ( $filesize )) $decr = 1024 ; $шаг = 0 ;
$prefix = array( 'Байт' , 'КБ' , 'МБ' , 'ГБ' , 'ТБ' , 'ПБ' );

while(($filesize / $decr) > 0,9) $filesize = $filesize / $decr;
$шаг++;
>
возврат раунда ( $filesize , 2 ). ' ' . $префикс [$шаг];
> еще

В этой статье я объясню основы загрузки файлов в PHP. Во-первых, мы рассмотрим параметры конфигурации PHP, которые необходимы для успешной загрузки файлов. После этого мы разработаем реальный пример загрузки файла.

Настройте параметры PHP

Есть несколько параметров конфигурации PHP, которые необходимо заранее проверить на предмет успешной загрузки файлов. В этом разделе мы рассмотрим все важные параметры загрузки файла PHP. Эти параметры можно настроить в файле php.ini.

Если вы не знаете, где найти файл php.ini, вы можете использовать функцию php_ini_loaded_file(), чтобы найти его. Просто создайте файл PHP на своем сервере со следующей строкой и откройте его в браузере.

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

Основные настройки

загрузки_файлов

Значение директивы file_uploads должно быть установлено на On, чтобы разрешить загрузку файлов. Значение по умолчанию для этой директивы — On .

upload_max_filesize

Директива upload_max_filesize позволяет настроить максимальный размер загружаемого файла. По умолчанию установлено значение 2M (два мегабайта), и вы также можете переопределить этот параметр с помощью файла .htaccess. Два мегабайта — это не так много по сегодняшним меркам, поэтому вам, возможно, придется увеличить это значение. Если вы получаете сообщение об ошибке, что файл превышает upload_max_filesize при попытке загрузить файл, вам необходимо увеличить это значение. Если вы это сделаете, не забудьте также увеличить post_max_size (см. ниже).

upload_tmp_dir

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

максимальный_размер сообщения

Директива post_max_size позволяет настроить максимальный размер данных POST. Поскольку файлы загружаются с помощью запросов POST, это значение должно быть больше, чем то, что вы установили для директивы upload_max_filesize. Например, если ваш upload_max_filesize равен 16 МБ (16 МБ), вы можете установить значение post_max_size равным 20 МБ .

max_file_uploads

Это позволяет вам установить максимальное количество файлов, которые можно загрузить за один раз. Значение по умолчанию – 20 – разумное количество.

max_input_time

Это максимальное количество секунд, в течение которого скрипту разрешено анализировать входные данные. Вы должны установить разумное значение, если вы имеете дело с загрузкой больших файлов. 60 (60 секунд) — хорошее значение для большинства приложений.

memory_limit

Директива memory_limit указывает максимальный объем памяти, который может потреблять сценарий. Если вы сталкиваетесь с проблемами при загрузке больших файлов, вам нужно убедиться, что значение этой директивы больше, чем то, что вы установили для директивы post_max_size. Значение по умолчанию – 128 М (128 мегабайт), поэтому, если у вас не очень большие значения post_max_size и upload_max_filesize , вам не о чем беспокоиться.

максимальное_время_исполнения

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

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

Создать HTML-форму

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

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

Мы собираемся создать два файла PHP: index.php и upload.php. Файл index.php содержит код, отвечающий за отображение формы загрузки файла. С другой стороны, файл upload.php отвечает за загрузку файла на сервер.

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

В этом разделе мы рассмотрим ключевые части файла index.php.

Давайте посмотрим на файл index.php на GitHub:

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

CSS в основном скрывает ввод исходного файла и стилизует сопровождающие его элементы span и label.

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

Атрибут enctype указывает тип кодировки, который следует использовать при отправке формы, и принимает одно из следующих трех значений:

  • application/x-www-form-urlencoded : это значение по умолчанию, если вы не устанавливаете значение атрибута enctype явно. В этом случае символы кодируются перед отправкой на сервер. Если в форме нет поля файла, следует использовать это значение для атрибута enctype.
  • multipart/form-data : использование значения multipart/form-data для атрибута enctype позволяет загружать файлы методом POST. Кроме того, он гарантирует, что символы не будут закодированы при отправке формы.
  • text/plain : обычно не используется. При использовании этого параметра данные отправляются в незакодированном виде.

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

Кроме того, мы отобразили сообщение в верхней части формы. Это сообщение показывает статус загрузки файла, и он будет установлен в переменной сеанса сценарием upload.php. Подробнее об этом мы поговорим в следующем разделе.

Итак, это подводит итог файлу index.php. В следующем разделе мы увидим, как обрабатывать загруженный файл на стороне сервера.

Создайте логику загрузки

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

Вставьте код из файла upload.php на GitHub. Мы рассмотрим важные части этого файла.

В файле upload.php мы в первую очередь проверили, является ли запрос POST допустимым.

В PHP при загрузке файла суперглобальная переменная $_FILES заполняется всей информацией о загруженном файле. Он инициализируется как массив и может содержать следующую информацию для успешной загрузки файла.

  • tmp_name : в этой переменной хранится временный путь, по которому загружается файл.
  • name : в этой переменной хранится фактическое имя файла.
  • size : указывает размер загруженного файла в байтах.
  • type : содержит MIME-тип загруженного файла.
  • error : если во время загрузки файла возникает ошибка, эта переменная заполняется соответствующим сообщением об ошибке. В случае успешной загрузки файла он содержит 0, что можно сравнить с помощью константы UPLOAD_ERR_OK.

После проверки запроса POST мы проверяем, что загрузка файла прошла успешно.

Вы можете видеть, что переменная $_FILES представляет собой многомерный массив, первый элемент которого представляет собой имя поля файла, а второй элемент содержит информацию о загруженном файле, как мы только что обсуждали выше.< /p>

Если загрузка файла прошла успешно, мы инициализируем несколько переменных информацией о загруженном файле.

В приведенном выше фрагменте мы также выяснили расширение загруженного файла и сохранили его в переменной $fileExtension.

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

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

Наконец, мы используем функцию move_uploaded_file, чтобы переместить загруженный файл в указанное место по нашему выбору.

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

Наконец, мы перенаправляем пользователя к файлу index.php. Также задаем в переменной сессии соответствующее сообщение, которое будет отображаться пользователям после перенаправления в файле index.php.

Как все это работает вместе

Не забудьте создать каталог uploaded_files и сделать его доступным для записи пользователю веб-сервера. Затем запустите файл index.php, который должен отобразить форму загрузки файла, которая выглядит следующим образом:

Интерфейс загрузки файлов
Интерфейс загрузки файлов
Интерфейс загрузки файлов

Нажмите кнопку «Обзор». Откроется диалоговое окно, позволяющее выбрать файл на вашем компьютере. Выберите файл с одним из разрешенных в нашем скрипте расширений и нажмите кнопку Загрузить.

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

Устранение распространенных ошибок

Во время загрузки файла многое может пойти не так, что может привести к ошибкам. Вы можете проверить точную ошибку, которая произошла во время загрузки, используя $_FILES['uploadedFile']['error'] . Вот объяснение этих ошибок:

Файл слишком большой

UPLOAD_ERR_INI_SIZE и UPLOAD_ERR_FORM_SIZE возникают, когда размер загруженного файла превышает значение, указанное в php.ini или форме HTML соответственно. Вы можете избавиться от этой ошибки, увеличив ограничения на размер загрузки или заранее сообщив об этом пользователям.

Временная папка отсутствует

Сообщается об отсутствии временной папки для загрузки файла UPLOAD_ERR_NO_TMP_DIR. UPLOAD_ERR_NO_FILE сообщается, когда нет файла для загрузки.

Частичная загрузка или не удается записать на диск

Вы получите UPLOAD_ERR_PARTIAL, если файл удалось загрузить только частично, и UPLOAD_ERR_CANT_WRITE, если файл не удалось записать на диск.

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

Иногда вы получаете сообщение об ошибке UPLOAD_ERR_EXTENSION, потому что какое-то расширение остановило загрузку файла. Это потребует от вас дополнительных исследований, чтобы выяснить, какое расширение вызвало проблему.

Вот полный код из upload.php, который покажет пользователям сообщение на странице загрузки в случае успеха или неудачи загрузки. Информация об успешной или неудачной загрузке хранится в $_SESSION['message'] .

Изучите PHP с помощью бесплатного онлайн-курса

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

Если вы хотите узнать больше о PHP, ознакомьтесь с нашим бесплатным онлайн-курсом по основам PHP!


В этом курсе вы изучите основы программирования на PHP. Вы начнете с основ, узнаете, как работает PHP, и напишете простые циклы и функции PHP. Затем вы перейдете к классам программирования для простого объектно-ориентированного программирования (ООП). Попутно вы освоите все самые важные навыки написания приложений для Интернета: у вас будет возможность попрактиковаться в ответах на запросы GET и POST, синтаксическом анализе JSON, аутентификации пользователей и использовании базы данных MySQL.

php-file-upload

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

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

Давайте начнем с нескольких простых примеров:

Для начала мы создадим следующее:

1. HTML-форма

Сначала мы создадим HTML-форму, которую пользователь увидит, когда захочет загрузить файл. Создайте новую папку для этого примера проекта и в ней создайте файл index.html со следующим кодом:

В приведенном выше примере следует отметить пару важных моментов:

  • action="fileUploadScript.php" — ссылка на PHP-скрипт, который будет обрабатывать загрузку файла на сервер.
  • method="post" – указывает действие браузера, которое форма будет использовать при отправке файла на сервер (для загрузки это почти всегда действие POST, иногда PUT).
  • enctype="multipart/form-data" – определяет тип содержимого, отправляемого формой.

Затем откройте терминал и из каталога, в котором вы создали файл, запустите сервер PHP:

php-file-upload

Затем откройте веб-браузер и перейдите на localhost:1234 . Вы должны увидеть что-то вроде этого:

php-file-upload

2. Скрипт загрузки файла PHP

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

Затем в том же каталоге, что и index.html, создайте файл с именем fileUploadScript.php. Обратите внимание, что это то же имя, что и у атрибута действия в форме. Затем добавьте этот код:

Несколько замечаний:

  • Ключ, используемый для доступа к файлу из объекта $_FILES, соответствует атрибуту имени, используемому в форме.
  • $fileName = $FILES['thefile']['name']; – Это имя фактического файла
  • $fileSize = $FILES['thefile']['size']; – Это размер файла в байтах.
  • $fileTmpName = $FILES['thefile']['tmp_name']; – Это временный файл, который находится в каталоге tmp сервера
  • $fileExtension = strtolower(end(explode('.',$fileName))); – Получает расширение файла из имени файла
  • $uploadPath = $currentDir . $uploadDirectory . базовое имя ($ имя_файла); – Здесь файлы будут храниться на сервере. В приведенном выше скрипте он установлен в текущий рабочий каталог

Также обратите внимание, что в приведенном выше коде мы проверяем загрузку файла, проверяя его тип и размер. (Только файлы png и jpeg размером менее 4 МБ)

Теперь осталось сделать пару последних шагов, прежде чем мы сможем начать загрузку файлов:

  • Перейдите в каталог uploads/ и сделайте его доступным для записи, выполнив: chmod 0755 uploads/
  • Убедитесь, что ваш файл php.ini правильно настроен для загрузки файлов (Совет: чтобы найти файл php.ini, запустите php --ini ):

Наконец, если теперь вы запустите сервер PHP и перейдете на localhost:1234, а затем загрузите файл, вы должны увидеть его сохранение в папке для загрузки!

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

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

Зачем обращаться к сторонним поставщикам, таким как Filestack, а не создавать их самостоятельно? При использовании третьей стороны вам больше не нужно заниматься масштабированием, безопасностью и обслуживанием, которые возникают при создании собственной системы загрузки файлов. Это позволит вам сосредоточиться на создании других важных частей вашего приложения.

И вы можете начать бесплатно. У Filestack есть бесплатный план, который обрабатывает до 100 ежемесячных загрузок с 1 ГБ хранилища и пропускной способностью 1 ГБ. Если вам нужно выйти за рамки этой суммы, они предлагают цены, которые масштабируются по мере использования.

Итак, приступим:

1. Зарегистрируйте учетную запись Filestack

php-file-upload

Сначала мы создадим учетную запись Filestack. Перейдите на их страницу регистрации и после входа в систему получите ключ API, который вы будете использовать на последующих этапах.

2. Начать загрузку

Теперь, когда у нас есть библиотека Filestack, давайте интегрируем их виджет загрузки файлов JavaScript, который позволит вашим пользователям подключаться к множеству других источников для загрузки. Например, если они хотели загрузить с URL-адреса или из социальных сетей. Просто замените содержимое index.html следующим:

Затем откройте свою страницу и загрузите файл с помощью виджета загрузки. После загрузки вы сможете войти в панель инструментов Filestack и увидеть только что загруженный файл:

filestack-dashboard

И все! Вам даже не нужен сервер для обработки файла, что лучше с точки зрения масштабируемости, безопасности и обслуживания.

Файловая библиотека PHP (необязательно)

В приведенном выше примере показан простейший пример загрузки файла с помощью Filestack. Но что, если вы хотите получить доступ к файлу на своем сервере, чтобы выполнить некоторую постобработку, например, проверить, безопасно ли изображение для работы? Для этого вы можете использовать PHP-библиотеку Filestack.Мы будем использовать Composer для установки PHP-библиотеки Filestack. Если у вас еще нет Composer, вы можете установить его, перейдя в созданную изначально папку и запустив ее (официальную документацию см. здесь):

После того, как вы сделаете это, вы сможете увидеть вывод Composer, запустив php composer.phar .

Затем запустите require --prefer-dist filestack/filestack-php, чтобы установить Filestack SDK.

Теперь, когда у нас есть библиотека Filestack, давайте создадим новый PHP-скрипт, чтобы проверить, безопасен ли конкретный загруженный файл для работы. Создайте новый файл с именем fileUploadFilestack.php и добавьте следующее (не забудьте изменить переменные YOUR_API_KEY, YOUR_SECURITY_SECRET и YOUR_FILE_HANDLE):

При запуске этого скрипта результат проверки работоспособности будет сохранен в переменной $json_result. И это только один пример. Использование Filestack PHP SDK позволяет выполнять различные задачи с загруженными файлами. Ознакомьтесь с другими примерами:

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

Обзор

Теперь, когда вы знаете, как реализовать загрузку файлов PHP двумя способами, вы можете легко добавить эту функцию на свой веб-сайт или в приложение. Если проблемы с масштабируемостью, безопасностью и обслуживанием при размещении собственной инфраструктуры загрузки файлов кажутся слишком сложными, позвольте Filestack справиться с этим. Также обязательно ознакомьтесь с нашей статьей о загрузке файлов AJAX!

Читайте также: