<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/features.file-upload.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'features.file-upload.post-method.php',
    1 => 'Загрузка файлов методом POST',
    2 => 'Загрузка файлов методом POST',
  ),
  'up' => 
  array (
    0 => 'features.file-upload.php',
    1 => 'Загрузка файлов на сервер',
  ),
  'prev' => 
  array (
    0 => 'features.file-upload.php',
    1 => 'Загрузка файлов на сервер',
  ),
  'next' => 
  array (
    0 => 'features.file-upload.errors.php',
    1 => 'Объяснение сообщений об ошибках',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'features/file-upload.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="features.file-upload.post-method" class="sect1">
  <h2 class="title">Загрузка файлов методом POST</h2>
  <p class="simpara">
   Через этот механизм загружают как текстовые, так и бинарные файлы.
   Через PHP-функции аутентификации и работы с файлами программист получает
   полный контроль над доступом к загрузке файлов на сервер и обработкой файла после загрузки.
  </p>
  <p class="simpara">
   PHP умеет принимать загруженные файлы из браузеров,
   которые совместимы со стандартом RFC-1867.
  </p>

  <blockquote class="note"><p><strong class="note">Замечание</strong>: 
   <strong>Смежные замечания по конфигурации</strong><br />
   <p class="para">
    Ознакомьтесь также с описанием директив конфигурационного
    файла <var class="filename">php.ini</var>:
    <a href="ini.core.php#ini.file-uploads" class="link">file_uploads</a>,
    <a href="ini.core.php#ini.upload-max-filesize" class="link">upload_max_filesize</a>,
    <a href="ini.core.php#ini.upload-tmp-dir" class="link">upload_tmp_dir</a>,
    <a href="ini.core.php#ini.post-max-size" class="link">post_max_size</a>
    и <a href="info.configuration.php#ini.max-input-time" class="link">max_input_time</a>.
   </p>
  </p></blockquote>

  <p class="para">
   PHP также поддерживает загрузку файлов методом PUT,
   через который загружают файлы на сервер клиенты <span class="productname">Netscape Composer</span>
   и <span class="productname">Amaya</span> консорциума W3C. Подробнее
   об этом методе рассказывает раздел
   «<a href="features.file-upload.put-method.php" class="link">Поддержка метода PUT</a>».
  </p>

  <p class="para">
   <div class="example" id="example-1">
    <p><strong>Пример #1 Форма для загрузки файлов</strong></p>
    <div class="example-contents"><p>
     Страница загрузки файлов на сервер реализуется
     через форму, которая выглядит примерно так:
    </p></div>
    <div class="example-contents">
<div class="htmlcode"><pre class="htmlcode">&lt;!-- Тип кодирования данных, enctype, требуется указывать только так, как показывает пример --&gt;
&lt;form enctype=&quot;multipart/form-data&quot; action=&quot;__URL__&quot; method=&quot;POST&quot;&gt;
    &lt;!-- Поле MAX_FILE_SIZE требуется указывать перед полем загрузки файла --&gt;
    &lt;input type=&quot;hidden&quot; name=&quot;MAX_FILE_SIZE&quot; value=&quot;30000&quot; /&gt;
    &lt;!-- Название элемента input определяет название элемента в суперглобальном массиве $_FILES --&gt;
    Отправить файл: &lt;input name=&quot;userfile&quot; type=&quot;file&quot; /&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Отправить файл&quot; /&gt;
&lt;/form&gt;</pre>
</div>
    </div>

    <div class="example-contents"><p>
     В приведённом примере значение <code class="literal">__URL__</code> нужно заменить ссылкой
     на PHP-файл.
    </p></div>
    <div class="example-contents"><p>
     Скрытое поле <code class="literal">MAX_FILE_SIZE</code> (значение
     требуется указывать в байтах) должно идти перед полем
     выбора файла. Значение поля указывает максимальный
     размер файла, который принимает PHP.
     Рекомендуется добавлять этот элемент в форму, поскольку
     он не заставляет пользователя ждать окончания передачи большого
     файла, а только потом узнавать, что файл оказался
     слишком большим и передача не состоялась.
     Имейте в виду: обойти это ограничение на стороне браузера
     легко, поэтому не рассчитывайте, что эта функция
     заблокирует файлы большего размера. Это только удобная функция
     для пользователей клиентской части приложения.
     Однако серверные PHP-настройки, которые касаются максимального размера,
     обойти невозможно.
    </p></div>
   </div>
  </p>

  <blockquote class="note"><p><strong class="note">Замечание</strong>: 
   <p class="para">
    Проверьте, что форма загрузки содержит атрибут
    <code class="literal">enctype=&quot;multipart/form-data&quot;</code>, иначе
    загрузка файлов на сервер не будет работать.
   </p>
  </p></blockquote>

  <p class="para">
   Суперглобальный массив <var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES</a></var> содержит полную информацию о файлах,
   которые загрузили на сервер. Содержимое массива после отправки приведённой формы выводит пример на этой странице.
   Обратите внимание, здесь элемент с выбором файла называется <em>userfile</em>,
   как в приведённом примере. Полю выбора файла разрешается присваивать произвольное имя.
   <dl>
    
     <dt><var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['name']</a></var></dt>
     <dd>
      <p class="para">
       Исходное название файла на компьютере клиента.
      </p>
     </dd>
    
    
     <dt><var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['type']</a></var></dt>
     <dd>
      <p class="para">
       MIME-тип файла, если браузер отправил такую информацию.
       Пример MIME-типа: «<code class="literal">image/gif</code>».
       MIME-тип не проверяется на стороне PHP, поэтому значение не принимают
       без проверки.
      </p>
     </dd>
    
    
     <dt><var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['size']</a></var></dt>
     <dd>
      <p class="para">
       Размер принятого файла в байтах.
      </p>
     </dd>
    
    
     <dt><var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['tmp_name']</a></var></dt>
     <dd>
      <p class="para">
       Временное имя файла, под которым PHP хранил файл, который загрузили на сервер.
      </p>
     </dd>
    
    
     <dt><var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['error']</a></var></dt>
     <dd>
      <p class="para">
       <a href="features.file-upload.errors.php" class="link">Код ошибки</a>,
       которая возникает при загрузке файла.
      </p>
     </dd>
    
    
     <dt><var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['full_path']</a></var></dt>
     <dd>
      <p class="para">
       Полный путь, который отправил браузер. Это значение не всегда содержит реальную структуру
       каталогов и ему нельзя доверять. Поле доступно с PHP 8.1.0.
      </p>
     </dd>
    
   </dl>
  </p>

  <p class="para">
   По умолчанию PHP сохраняет принятые файлы на сервере в стандартной
   вре́менной папке до тех пор, пока через директиву <a href="ini.core.php#ini.upload-tmp-dir" class="link">upload_tmp_dir</a>
   конфигурационного файла <var class="filename">php.ini</var> не зададут другой каталог.
   На сервере директорию по умолчанию можно изменить через переменную <var class="envar">TMPDIR</var> того окружения,
   в котором работает PHP. Установка переменной
   функцией <span class="function"><a href="function.putenv.php" class="function">putenv()</a></span> внутри PHP-скрипта работать
   не будет. Через эту переменную окружения также проверяют,
   что другие операции тоже работают с принятыми файлами.
   <div class="example" id="example-2">
    <p><strong>Пример #2 Проверка файлов, которые загрузили на сервер</strong></p>
    <div class="example-contents"><p>
     Дополнительную информацию дают описания функций
     <span class="function"><a href="function.is-uploaded-file.php" class="function">is_uploaded_file()</a></span>
     и <span class="function"><a href="function.move-uploaded-file.php" class="function">move_uploaded_file()</a></span>. Следующий пример
     принимает и обрабатывает файл, который загрузили на сервер через форму.
    </p></div>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$uploaddir </span><span style="color: #007700">= </span><span style="color: #DD0000">'/var/www/uploads/'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$uploadfile </span><span style="color: #007700">= </span><span style="color: #0000BB">$uploaddir </span><span style="color: #007700">. </span><span style="color: #0000BB">basename</span><span style="color: #007700">(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #DD0000">'userfile'</span><span style="color: #007700">][</span><span style="color: #DD0000">'name'</span><span style="color: #007700">]);<br /><br />echo </span><span style="color: #DD0000">'&lt;pre&gt;'</span><span style="color: #007700">;<br />if (</span><span style="color: #0000BB">move_uploaded_file</span><span style="color: #007700">(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #DD0000">'userfile'</span><span style="color: #007700">][</span><span style="color: #DD0000">'tmp_name'</span><span style="color: #007700">], </span><span style="color: #0000BB">$uploadfile</span><span style="color: #007700">)) {<br />    echo </span><span style="color: #DD0000">"Файл не содержит ошибок и успешно загрузился на сервер.\n"</span><span style="color: #007700">;<br />} else {<br />    echo </span><span style="color: #DD0000">"Возможная атака на сервер через загрузку файла!\n"</span><span style="color: #007700">;<br />}<br /><br />echo </span><span style="color: #DD0000">'Дополнительная отладочная информация:'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">print_r</span><span style="color: #007700">(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">);<br /><br />print </span><span style="color: #DD0000">"&lt;/pre&gt;"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
   <p class="simpara">
    PHP-скрипт, который принимает файл, должен реализовывать логику
    определения того, что требуется сделать с файлом, который загрузили на сервер.
    Можно, например, проверить переменную <var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['size']</a></var>,
    чтобы отсечь чрезмерно большие или слишком мелкие файлы. Можно также
    использовать переменную <var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['type']</a></var>,
    чтобы выбросить файлы, которые не соответствуют заданным критериям типа файла.
    Но выполняйте такую проверку только как первую в серии проверок, потому что это значение
    контролируется клиентом и не проверяется на стороне PHP.
    Кроме того, можно использовать переменную <var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['error']</a></var>
    и планировать логику поведения кода с учётом <a href="features.file-upload.errors.php" class="link">кодов ошибок</a>.
    При любой логике требуется либо удалить файл из временного каталога,
    либо переместить файл в другую директорию.
   </p>
   <p class="simpara">
    Если при отправке формы файл не выбрали, PHP установит
    для переменной <var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['size']</a></var> значение 0, а переменной
    <var class="varname"><a href="reserved.variables.files.php" class="classname">$_FILES['userfile']['tmp_name']</a></var> — none.
   </p>
   <p class="simpara">
    PHP удалит файл из временного каталога в конце запроса, если файл не переместили
    или не переименовали.
   </p>
   <div class="example" id="example-3">
    <p><strong>Пример #3 Загрузка массива файлов</strong></p>
    <div class="example-contents"><p>
     PHP поддерживает <a href="faq.html.php#faq.html.arrays" class="link">передачу массива из HTML-формы</a>
     даже с файлами.
    </p></div>
    <div class="example-contents">
<div class="htmlcode"><pre class="htmlcode">&lt;form action=&quot;&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
    &lt;p&gt;Изображения:
        &lt;input type=&quot;file&quot; name=&quot;pictures[]&quot; /&gt;
        &lt;input type=&quot;file&quot; name=&quot;pictures[]&quot; /&gt;
        &lt;input type=&quot;file&quot; name=&quot;pictures[]&quot; /&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Отправить&quot; /&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
</div>
    </div>

    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">foreach (</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #DD0000">"pictures"</span><span style="color: #007700">][</span><span style="color: #DD0000">"error"</span><span style="color: #007700">] as </span><span style="color: #0000BB">$key </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$error</span><span style="color: #007700">) {<br />    if (</span><span style="color: #0000BB">$error </span><span style="color: #007700">== </span><span style="color: #0000BB">UPLOAD_ERR_OK</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$tmp_name </span><span style="color: #007700">= </span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #DD0000">"pictures"</span><span style="color: #007700">][</span><span style="color: #DD0000">"tmp_name"</span><span style="color: #007700">][</span><span style="color: #0000BB">$key</span><span style="color: #007700">];<br /><br />        </span><span style="color: #FF8000">// Функция basename() помогает защититься от атак на файловую систему;<br />        // иногда требуется дополнительная проверка или очистка имени файла<br />        </span><span style="color: #0000BB">$name </span><span style="color: #007700">= </span><span style="color: #0000BB">basename</span><span style="color: #007700">(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #DD0000">"pictures"</span><span style="color: #007700">][</span><span style="color: #DD0000">"name"</span><span style="color: #007700">][</span><span style="color: #0000BB">$key</span><span style="color: #007700">]);<br />        </span><span style="color: #0000BB">move_uploaded_file</span><span style="color: #007700">(</span><span style="color: #0000BB">$tmp_name</span><span style="color: #007700">, </span><span style="color: #DD0000">"data/</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">"</span><span style="color: #007700">);<br />    }<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

   </div>
   <p class="para">
    Полосу прогресса загрузки файлов можно реализовать через
    «<a href="session.upload-progress.php" class="link">Отслеживание прогресса загрузки файлов через сессии</a>».
   </p>
  </div><?php manual_footer($setup); ?>