Загрузка файлов методом POST
  
   Через этот механизм загружают как текстовые, так и бинарные файлы.
   Через PHP-функции аутентификации и работы с файлами программист получает
   полный контроль над доступом к загрузке файлов на сервер и обработкой файла после загрузки.
  
  
   PHP умеет принимать загруженные файлы из браузеров,
   которые совместимы со стандартом RFC-1867.
  
  Замечание: 
   Смежные замечания по конфигурации
   
    Ознакомьтесь также с описанием директив конфигурационного
    файла php.ini:
    file_uploads,
    upload_max_filesize,
    upload_tmp_dir,
    post_max_size
    и max_input_time.
   
  
  
   PHP также поддерживает загрузку файлов методом PUT,
   через который загружают файлы на сервер клиенты Netscape Composer
   и Amaya консорциума W3C. Подробнее
   об этом методе рассказывает раздел
   «Поддержка метода PUT».
  
  
   
    Пример #1 Форма для загрузки файлов
    
     Страница загрузки файлов на сервер реализуется
     через форму, которая выглядит примерно так:
    
<!-- Тип кодирования данных, enctype, требуется указывать только так, как показывает пример -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- Поле MAX_FILE_SIZE требуется указывать перед полем загрузки файла -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Название элемента input определяет название элемента в суперглобальном массиве $_FILES -->
    Отправить файл: <input name="userfile" type="file" />
    <input type="submit" value="Отправить файл" />
</form>
 
    
     В приведённом примере значение __URL__ нужно заменить ссылкой
     на PHP-файл.
    
     Скрытое поле MAX_FILE_SIZE (значение
     требуется указывать в байтах) должно идти перед полем
     выбора файла. Значение поля указывает максимальный
     размер файла, который принимает PHP.
     Рекомендуется добавлять этот элемент в форму, поскольку
     он не заставляет пользователя ждать окончания передачи большого
     файла, а только потом узнавать, что файл оказался
     слишком большим и передача не состоялась.
     Имейте в виду: обойти это ограничение на стороне браузера
     легко, поэтому не рассчитывайте, что эта функция
     заблокирует файлы большего размера. Это только удобная функция
     для пользователей клиентской части приложения.
     Однако серверные PHP-настройки, которые касаются максимального размера,
     обойти невозможно.
    
 
  
  Замечание: 
   
    Проверьте, что форма загрузки содержит атрибут
    enctype="multipart/form-data", иначе
    загрузка файлов на сервер не будет работать.
   
  
  
   Суперглобальный массив $_FILES содержит полную информацию о файлах,
   которые загрузили на сервер. Содержимое массива после отправки приведённой формы выводит пример на этой странице.
   Обратите внимание, здесь элемент с выбором файла называется userfile,
   как в приведённом примере. Полю выбора файла разрешается присваивать произвольное имя.
   
    
     - $_FILES['userfile']['name']
- 
      
       Исходное название файла на компьютере клиента.
       
- $_FILES['userfile']['type']
- 
      
       MIME-тип файла, если браузер отправил такую информацию.
       Пример MIME-типа: «image/gif».
       MIME-тип не проверяется на стороне PHP, поэтому значение не принимают
       без проверки.
 
- $_FILES['userfile']['size']
- 
      
       Размер принятого файла в байтах.
       
- $_FILES['userfile']['tmp_name']
- 
      
       Временное имя файла, под которым PHP хранил файл, который загрузили на сервер.
       
- $_FILES['userfile']['error']
- 
      
       Код ошибки,
       которая возникает при загрузке файла.
       
- $_FILES['userfile']['full_path']
- 
      
       Полный путь, который отправил браузер. Это значение не всегда содержит реальную структуру
       каталогов и ему нельзя доверять. Поле доступно с PHP 8.1.0.
       
   По умолчанию PHP сохраняет принятые файлы на сервере в стандартной
   вре́менной папке до тех пор, пока через директиву upload_tmp_dir
   конфигурационного файла php.ini не зададут другой каталог.
   На сервере директорию по умолчанию можно изменить через переменную TMPDIR того окружения,
   в котором работает PHP. Установка переменной
   функцией putenv() внутри PHP-скрипта работать
   не будет. Через эту переменную окружения также проверяют,
   что другие операции тоже работают с принятыми файлами.
   
    Пример #2 Проверка файлов, которые загрузили на сервер
    
     Дополнительную информацию дают описания функций
     is_uploaded_file()
     и move_uploaded_file(). Следующий пример
     принимает и обрабатывает файл, который загрузили на сервер через форму.
    
<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "Файл не содержит ошибок и успешно загрузился на сервер.\n";
} else {
    echo "Возможная атака на сервер через загрузку файла!\n";
}
echo 'Дополнительная отладочная информация:';
print_r($_FILES);
print "</pre>";
?>
      
     
   
   
    PHP-скрипт, который принимает файл, должен реализовывать логику
    определения того, что требуется сделать с файлом, который загрузили на сервер.
    Можно, например, проверить переменную $_FILES['userfile']['size'],
    чтобы отсечь чрезмерно большие или слишком мелкие файлы. Можно также
    использовать переменную $_FILES['userfile']['type'],
    чтобы выбросить файлы, которые не соответствуют заданным критериям типа файла.
    Но выполняйте такую проверку только как первую в серии проверок, потому что это значение
    контролируется клиентом и не проверяется на стороне PHP.
    Кроме того, можно использовать переменную $_FILES['userfile']['error']
    и планировать логику поведения кода с учётом кодов ошибок.
    При любой логике требуется либо удалить файл из временного каталога,
    либо переместить файл в другую директорию.
   
   
    Если при отправке формы файл не выбрали, PHP установит
    для переменной $_FILES['userfile']['size'] значение 0, а переменной
    $_FILES['userfile']['tmp_name'] — none.
   
   
    PHP удалит файл из временного каталога в конце запроса, если файл не переместили
    или не переименовали.
   
   
    Пример #3 Загрузка массива файлов
    
     PHP поддерживает передачу массива из HTML-формы
     даже с файлами.
    
<form action="" method="post" enctype="multipart/form-data">
    <p>Изображения:
        <input type="file" name="pictures[]" />
        <input type="file" name="pictures[]" />
        <input type="file" name="pictures[]" />
        <input type="submit" value="Отправить" />
    </p>
</form>
 
    
<?php
foreach ($_FILES["pictures"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["pictures"]["tmp_name"][$key];
        // Функция basename() помогает защититься от атак на файловую систему;
        // иногда требуется дополнительная проверка или очистка имени файла
        $name = basename($_FILES["pictures"]["name"][$key]);
        move_uploaded_file($tmp_name, "data/$name");
    }
}
?>
      
    
   
    Полосу прогресса загрузки файлов можно реализовать через
    «Отслеживание прогресса загрузки файлов через сессии».