mirror of
https://github.com/php/doc-ru.git
synced 2025-08-16 18:22:04 +00:00
624 lines
32 KiB
XML
624 lines
32 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 04d9aded7bbd447523cf038ddf88e6d7f7e43c53 Maintainer: shein Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<chapter xml:id="features.file-upload" xmlns="http://docbook.org/ns/docbook">
|
||
<title>Загрузка файлов на сервер</title>
|
||
|
||
<sect1 xml:id="features.file-upload.post-method">
|
||
<title>Загрузка файлов методом POST</title>
|
||
<simpara>
|
||
Через этот механизм загружают как текстовые, так и бинарные файлы.
|
||
Через PHP-функции аутентификации и работы с файлами программист получает
|
||
полный контроль над тем, кому можно загружать файлы на сервер, и что делать с файлом после загрузки.
|
||
</simpara>
|
||
<simpara>
|
||
PHP умеет принимать загруженные файлы из браузеров,
|
||
которые совместимы со стандартом RFC-1867.
|
||
</simpara>
|
||
|
||
<note>
|
||
<title>Смежные замечания по конфигурации</title>
|
||
<para>
|
||
Ознакомьтесь также с описанием директив конфигурационного
|
||
файла &php.ini;:
|
||
<link linkend="ini.file-uploads">file_uploads</link>,
|
||
<link linkend="ini.upload-max-filesize">upload_max_filesize</link>,
|
||
<link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>,
|
||
<link linkend="ini.post-max-size">post_max_size</link>
|
||
и <link linkend="ini.max-input-time">max_input_time</link>.
|
||
</para>
|
||
</note>
|
||
|
||
<para>
|
||
PHP также поддерживает загрузку файлов методом PUT,
|
||
через который загружают файлы на сервер клиенты <productname>Netscape Composer</productname>
|
||
и <productname>Amaya</productname> консорциума W3C. Подробнее
|
||
об этом методе рассказывает раздел
|
||
«<link linkend="features.file-upload.put-method">Поддержка метода PUT</link>».
|
||
</para>
|
||
|
||
<para>
|
||
<example>
|
||
<title>Форма для загрузки файлов</title>
|
||
<para>
|
||
Страница загрузки файлов на сервер реализуется
|
||
через форму, которая выглядит примерно так:
|
||
</para>
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<!-- Тип кодирования данных, 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>
|
||
]]>
|
||
</programlisting>
|
||
<para>
|
||
В приведённом примере значение <literal>__URL__</literal> нужно заменить ссылкой
|
||
на PHP-файл.
|
||
</para>
|
||
<para>
|
||
Скрытое поле <literal>MAX_FILE_SIZE</literal> (значение
|
||
требуется указывать в байтах) должно идти перед полем
|
||
выбора файла. Значение поля указывает максимальный
|
||
размер файла, который принимает PHP.
|
||
Рекомендуется добавлять этот элемент в форму, поскольку
|
||
он не заставляет пользователя ждать окончания передачи большого
|
||
файла, а только потом узнавать, что файл оказался
|
||
слишком большим и передача не состоялась.
|
||
Имейте в виду: обойти это ограничение на стороне браузера
|
||
легко, поэтому не рассчитывайте, что эта функция
|
||
заблокирует файлы большего размера. Это только удобная функция
|
||
для пользователей клиентской части приложения.
|
||
Однако серверные PHP-настройки, которые касаются максимального размера,
|
||
обойти невозможно.
|
||
</para>
|
||
</example>
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Проверьте, что форма загрузки содержит атрибут
|
||
<literal>enctype="multipart/form-data"</literal>, иначе
|
||
загрузка файлов на сервер не будет работать.
|
||
</para>
|
||
</note>
|
||
|
||
<para>
|
||
Суперглобальный массив <varname>$_FILES</varname> содержит полную информацию о файлах,
|
||
которые загрузили на сервер. Содержимое массива после отправки приведённой формы выводит пример на этой странице.
|
||
Обратите внимание, здесь элемент с выбором файла называется <emphasis>userfile</emphasis>,
|
||
как в приведённом примере. Полю выбора файла разрешается присваивать произвольное имя.
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><varname>$_FILES['userfile']['name']</varname></term>
|
||
<listitem>
|
||
<para>
|
||
Исходное название файла на компьютере клиента.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><varname>$_FILES['userfile']['type']</varname></term>
|
||
<listitem>
|
||
<para>
|
||
MIME-тип файла, если браузер отправил такую информацию.
|
||
Пример MIME-типа: «<literal>image/gif</literal>».
|
||
MIME-тип не проверяется на стороне PHP, поэтому значение не принимают
|
||
без проверки.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><varname>$_FILES['userfile']['size']</varname></term>
|
||
<listitem>
|
||
<para>
|
||
Размер принятого файла в байтах.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><varname>$_FILES['userfile']['tmp_name']</varname></term>
|
||
<listitem>
|
||
<para>
|
||
Временное имя файла, под которым PHP хранил файл, который загрузили на сервер.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><varname>$_FILES['userfile']['error']</varname></term>
|
||
<listitem>
|
||
<para>
|
||
<link linkend="features.file-upload.errors">Код ошибки</link>,
|
||
которая возникает при загрузке файла.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><varname>$_FILES['userfile']['full_path']</varname></term>
|
||
<listitem>
|
||
<para>
|
||
Полный путь, который отправил браузер. Это значение не всегда содержит реальную структуру
|
||
каталогов и ему нельзя доверять. Поле доступно с PHP 8.1.0.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
|
||
<para>
|
||
По умолчанию PHP сохраняет принятые файлы на сервере в стандартной
|
||
вре́менной папке до тех пор, пока через директиву <link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>
|
||
конфигурационного файла &php.ini; не зададут другой каталог.
|
||
На сервере директорию по умолчанию можно изменить через переменную <envar>TMPDIR</envar> того окружения,
|
||
в котором работает PHP. Установка переменной
|
||
функцией <function>putenv</function> внутри PHP-скрипта работать
|
||
не будет. Через эту переменную окружения также проверяют,
|
||
что другие операции тоже работают с принятыми файлами.
|
||
<example>
|
||
<title>Проверка файлов, которые загрузили на сервер</title>
|
||
<para>
|
||
Дополнительную информацию дают описания функций
|
||
<function>is_uploaded_file</function>
|
||
и <function>move_uploaded_file</function>. Следующий пример
|
||
принимает и обрабатывает файл, который загрузили на сервер через форму.
|
||
</para>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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>";
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
PHP-скрипт, который принимает файл, должен реализовывать логику
|
||
определения того, что требуется сделать с файлом, который загрузили на сервер.
|
||
Можно, например, проверить переменную <varname>$_FILES['userfile']['size']</varname>,
|
||
чтобы отсечь чрезмерно большие или слишком мелкие файлы. Можно также
|
||
использовать переменную <varname>$_FILES['userfile']['type']</varname>,
|
||
чтобы выбросить файлы, которые не соответствуют заданным критериям типа файла.
|
||
Но выполняйте такую проверку только как первую в серии проверок, потому что это значение
|
||
контролируется клиентом и не проверяется на стороне PHP.
|
||
Кроме того, можно использовать переменную <varname>$_FILES['userfile']['error']</varname>
|
||
и планировать логику поведения кода с учётом <link linkend="features.file-upload.errors">кодов ошибок</link>.
|
||
При любой логике требуется либо удалить файл из временного каталога,
|
||
либо переместить файл в другую директорию.
|
||
</simpara>
|
||
<simpara>
|
||
Если при отправке формы файл не выбрали, PHP установит
|
||
для переменной <varname>$_FILES['userfile']['size']</varname> значение 0, а переменной
|
||
<varname>$_FILES['userfile']['tmp_name']</varname> — none.
|
||
</simpara>
|
||
<simpara>
|
||
PHP удалит файл из временного каталога в конце запроса, если файл не переместили
|
||
или не переименовали.
|
||
</simpara>
|
||
<example>
|
||
<title>Загрузка массива файлов</title>
|
||
<para>
|
||
PHP поддерживает <link linkend="faq.html.arrays">передачу массива из HTML-формы</link>
|
||
даже с файлами.
|
||
</para>
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<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>
|
||
]]>
|
||
</programlisting>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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");
|
||
}
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<para>
|
||
Полосу прогресса загрузки файлов можно реализовать через
|
||
«<link linkend="session.upload-progress">Отслеживание прогресса загрузки файлов через сессии</link>».
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="features.file-upload.errors">
|
||
<title>Объяснение сообщений об ошибках</title>
|
||
<simpara>
|
||
PHP наряду с другими атрибутами принятого файла возвращает код ошибки.
|
||
Код ошибки хранится в массиве, который PHP создаёт
|
||
при загрузке файла, и доступен при обращении по ключу
|
||
<literal>error</literal>. Другими словами, код ошибки
|
||
находят в переменной <varname>$_FILES['userfile']['error']</varname>.
|
||
</simpara>
|
||
<para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_OK</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 0; ошибки не возникали, файл успешно загрузился на сервер.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_INI_SIZE</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 1; размер принятого файла превысил максимально допустимый
|
||
размер, который задали директивой <link linkend="ini.upload-max-filesize">upload_max_filesize</link>
|
||
конфигурационного файла &php.ini;.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_FORM_SIZE</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 2; размер загружаемого файла превысил значение <emphasis>MAX_FILE_SIZE</emphasis>,
|
||
которое указали в HTML-форме.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_PARTIAL</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 3; PHP получил загружаемый файл частично.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_NO_FILE</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 4; файл не загрузился.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_NO_TMP_DIR</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 6; отсутствует временная папка.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_CANT_WRITE</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 7; не удалось записать файл на диск.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><constant>UPLOAD_ERR_EXTENSION</constant></term>
|
||
<listitem>
|
||
<para>
|
||
Значение: 8; модуль PHP остановил загрузку файла. PHP
|
||
не даёт способа определить, какой модуль остановил
|
||
загрузку файла; в этом помогает просмотр списка загруженных
|
||
модулей, который возвращает функция <function>phpinfo</function>.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="features.file-upload.common-pitfalls">
|
||
<title>Распространённые подводные камни</title>
|
||
<simpara>
|
||
Элементу <literal>MAX_FILE_SIZE</literal> нельзя указывать размер файла,
|
||
который превышает предел, который установили в директиве
|
||
<link linkend="ini.upload-max-filesize">upload_max_filesize</link> файла &php.ini;.
|
||
Ограничение по умолчанию составляет 2 мегабайта.
|
||
</simpara>
|
||
<simpara>
|
||
Если установили ограничения памяти, может потребоваться
|
||
увеличение значения опции <link linkend="ini.memory-limit">memory_limit</link>.
|
||
Убедитесь, что значение директивы <link linkend="ini.memory-limit">memory_limit</link>
|
||
достаточно.
|
||
</simpara>
|
||
<simpara>
|
||
Время, которое потребуется для работы скрипта, может превысить
|
||
значение опции <link linkend="ini.max-execution-time">max_execution_time</link>,
|
||
если для директивы установили маленькое значение.
|
||
Убедитесь, что значение директивы <literal>max_execution_time</literal> достаточно.
|
||
</simpara>
|
||
<note>
|
||
<simpara>
|
||
Директива <link linkend="ini.max-execution-time">max_execution_time</link>
|
||
влияет только на время выполнения самого скрипта.
|
||
Время, которое заняли действия за пределами скрипта, — системные вызовы
|
||
функций <function>system</function> или <function>sleep</function>, запросы
|
||
к базе данных, время, которое заняла загрузка файла на сервер, и т. д. —
|
||
не учитывается при определении максимального времени работы скрипта.
|
||
</simpara>
|
||
</note>
|
||
<warning>
|
||
<simpara>
|
||
Директива <link linkend="ini.max-input-time">max_input_time</link> устанавливает
|
||
максимальное время в секундах, в течение которого скрипту разрешается получать входные данные;
|
||
время загрузки файла тоже включается. Загрузка больших файлов, набора файлов
|
||
или обработка запросов пользователей с медленными соединениями может превысить значение по умолчанию
|
||
в <literal>60</literal> секунд.
|
||
</simpara>
|
||
</warning>
|
||
<simpara>
|
||
Сервер не загрузит большие файлы, если
|
||
для директивы <link linkend="ini.post-max-size">post_max_size</link>
|
||
установили слишком маленькое значение.
|
||
Проверьте, что значение директивы <literal>post_max_size</literal> достаточно.
|
||
</simpara>
|
||
<simpara>
|
||
Опция
|
||
<link linkend="ini.max-file-uploads">max_file_uploads</link>
|
||
контролирует максимальное количество файлов, которые загружают на сервер в течение
|
||
одного запроса. Суперглобальный массив <varname>$_FILES</varname>
|
||
прекратит обработку файлов, как только достигнет ограничения,
|
||
если загружается больше файлов, чем в ограничении.
|
||
Например, если значение директивы
|
||
<link linkend="ini.max-file-uploads">max_file_uploads</link> равняется
|
||
<literal>10</literal>, массив <varname>$_FILES</varname> не будет
|
||
содержать больше 10 элементов.
|
||
</simpara>
|
||
<simpara>
|
||
Без проверки того, с каким файлом ведётся работа, пользователи смогут
|
||
получить доступ к конфиденциальной информации других каталогов.
|
||
</simpara>
|
||
<simpara>
|
||
Из-за многообразия стилей, в которых файловые системы ведут список каталогов,
|
||
PHP не гарантирует правильную обработку файлов с экзотическими именами,
|
||
например файлов с пробелами в именах.
|
||
</simpara>
|
||
<simpara>
|
||
Разработчикам нельзя смешивать обычные <literal>input</literal>-поля и поля загрузки файлов
|
||
в одной и той же переменной формы (например, нельзя указывать в имени <literal>input</literal>-элемента
|
||
значение <literal>foo[]</literal>).
|
||
</simpara>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="features.file-upload.multiple">
|
||
<title>Загрузка нескольких файлов</title>
|
||
<simpara>
|
||
Набор файлов загружают через разные значения
|
||
атрибута <literal>name</literal> в <literal>input</literal>-элементах формы.
|
||
</simpara>
|
||
<simpara>
|
||
Возможно также загружать набор файлов одновременно
|
||
и автоматически получать файлы в виде массива.
|
||
Для этого в HTML-форме пользуются тем же синтаксисом отправки массива,
|
||
что и для отправки списка значений через HTML-элементы SELECT или поля ввода с типом checkbox:
|
||
</simpara>
|
||
<para>
|
||
<example>
|
||
<title>Загрузка нескольких файлов</title>
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<form action="file-upload.php" method="post" enctype="multipart/form-data">
|
||
Файлы:<br />
|
||
<input name="userfile[]" type="file" /><br />
|
||
<input name="userfile[]" type="file" /><br />
|
||
<input type="submit" value="Отправить" />
|
||
</form>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
При отправке приведённой формы PHP инициализирует массивы
|
||
<varname>$_FILES['userfile']</varname>,
|
||
<varname>$_FILES['userfile']['name']</varname>
|
||
и <varname>$_FILES['userfile']['size']</varname>.
|
||
</simpara>
|
||
<simpara>
|
||
Предположим, что отправили файлы
|
||
<filename>/home/test/review.html</filename>
|
||
и <filename>/home/test/xwp.out</filename>. Тогда переменная
|
||
<varname>$_FILES['userfile']['name'][0]</varname> будет содержать значение
|
||
<filename>review.html</filename>, а переменная
|
||
<varname>$_FILES['userfile']['name'][1]</varname> —
|
||
<filename>xwp.out</filename>. Аналогично, переменная
|
||
<varname>$_FILES['userfile']['size'][0]</varname> будет содержать размер
|
||
файла <filename>review.html</filename> и так далее.
|
||
</simpara>
|
||
<simpara>
|
||
PHP также инициализирует переменные <varname>$_FILES['userfile']['name'][0]</varname>,
|
||
<varname>$_FILES['userfile']['tmp_name'][0]</varname>,
|
||
<varname>$_FILES['userfile']['size'][0]</varname>
|
||
и <varname>$_FILES['userfile']['type'][0]</varname>.
|
||
</simpara>
|
||
<warning>
|
||
<simpara>
|
||
Параметр конфигурации
|
||
<link linkend="ini.max-file-uploads">max_file_uploads</link>
|
||
ограничивает количество файлов, которое разрешается загружать
|
||
за один запрос. Потребуется проверить, что форма
|
||
не пытается загрузить за один запрос больше файлов, чем ограничение.
|
||
</simpara>
|
||
</warning>
|
||
<para>
|
||
<example>
|
||
<title>Загрузка каталога</title>
|
||
<simpara>
|
||
В HTML-полях выбора файла для загрузки указывают атрибут <literal>webkitdirectory</literal>,
|
||
чтобы загрузить весь каталог.
|
||
Бо́льшая часть браузеров поддерживает эту функцию.
|
||
</simpara>
|
||
<simpara>
|
||
Информация, которую хранит элемент <literal>full_path</literal>, помогает сохранить
|
||
относительные пути или воссоздать такой же каталог на сервере.
|
||
</simpara>
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<form action="file-upload.php" method="post" enctype="multipart/form-data">
|
||
Загрузка каталога:<br />
|
||
<input name="userfile[]" type="file" webkitdirectory multiple />
|
||
<input type="submit" value="Загрузить файлы" />
|
||
</form>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Атрибут <literal>webkitdirectory</literal> нестандартен и не соответствует спецификациям.
|
||
Не рекомендуется включать атрибут в элементы форм на рабочих сайтах: атрибут работает не у каждого пользователя.
|
||
Способ обработки атрибута несовместим между браузерами, и поведение могут изменить в будущих выпусках.
|
||
</simpara>
|
||
<simpara>
|
||
PHP анализирует только информацию об относительном пути, которую отправили браузер или пользовательский агент,
|
||
и передаёт информацию в суперглобальный массив <varname>$_FILES</varname>.
|
||
Нет гарантии, что значения в массиве <literal>full_path</literal> содержат реальную структуру каталогов,
|
||
и PHP-приложение не должно доверять этой информации.
|
||
</simpara>
|
||
</warning>
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="features.file-upload.put-method">
|
||
<title>Поддержка метода PUT</title>
|
||
<para>
|
||
PHP поддерживает HTTP-метод PUT, через который отдельные клиенты
|
||
отправляют файлы на сервер для хранения.
|
||
PUT-запросы проще, чем загрузка файлов POST-запросами, а выглядят PUT-запросы примерно так:
|
||
<informalexample>
|
||
<programlisting role="HTTP">
|
||
<![CDATA[
|
||
PUT /path/filename.html HTTP/1.1
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<para>
|
||
Обычно такой вызов означает, что удалённый клиент хотел бы сохранить
|
||
файл <filename>/path/filename.html</filename>
|
||
в дереве каталогов веб-сервера.
|
||
Не сомневаемся, что настраивать веб-сервер Apache или PHP так, чтобы они разрешали
|
||
каждому автоматически перезаписывать файлы веб-сервера, — плохая идея.
|
||
Поэтому, чтобы обработать такой запрос, потребуется сначала сообщить веб-серверу, чтобы
|
||
запрос обрабатывал конкретный PHP-скрипт. На веб-сервере Apache
|
||
это делается через директиву <emphasis>Script</emphasis>.
|
||
Обычно директиву записывают в произвольном месте конфигурационного файла веб-сервера Apache
|
||
внутри блока <literal><Directory></literal> или, возможно, внутри блока
|
||
<literal><VirtualHost></literal>. Строка наподобие этой
|
||
укажет веб-серверу конкретный PHP-файл для обработки запроса:
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
Script PUT /put.php
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<simpara>
|
||
Строка говорит веб-серверу Apache перенаправлять
|
||
каждый PUT-запрос к URI-идентификаторам, которые соответствуют контексту,
|
||
в котором записали строку, в файл <filename>put.php</filename>.
|
||
Предполагается, что файлы с расширением <filename class="extension">.php</filename>
|
||
обрабатываются как PHP-скрипты, и что сам PHP активен.
|
||
Ресурсом назначения для PUT-запросов к этому скрипту должен
|
||
быть сам скрипт, а не имя, которое требуется дать загружаемому файлу.
|
||
</simpara>
|
||
<simpara>
|
||
Затем внутри файла put.php разработчик мог бы написать код наподобие следующего примера.
|
||
Пример скопирует содержимое загруженного файла в файл <filename>myputfile.ext</filename> на сервере.
|
||
Возможно, потребуются проверки и (или) аутентификация пользователя перед копированием файла.
|
||
</simpara>
|
||
<para>
|
||
<example>
|
||
<title>Сохранение файлов, которые отправили HTTP-методом PUT</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
/* PUT-данные приходят в стандартный поток входных данных stdin */
|
||
$putdata = fopen("php://input", "r");
|
||
|
||
/* Открываем файл для записи */
|
||
$fp = fopen("myputfile.ext", "w");
|
||
|
||
/* Читаем 1 KB данных за один раз
|
||
и записываем в файл */
|
||
while ($data = fread($putdata, 1024)) {
|
||
fwrite($fp, $data);
|
||
}
|
||
|
||
/* Закрываем потоки */
|
||
fclose($fp);
|
||
fclose($putdata);
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="features.file-upload.errors.seealso">
|
||
&reftitle.seealso;
|
||
<para>
|
||
<simplelist>
|
||
<member><link linkend="security.filesystem">Безопасность файловой системы</link></member>
|
||
</simplelist>
|
||
</para>
|
||
</sect1>
|
||
|
||
</chapter>
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|