Updated translation.

git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@307874 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Shein Alexey
2011-01-31 11:15:12 +00:00
parent 3d4b466d89
commit 1a72beb503

View File

@ -1,103 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: dd144da0e1bb146063e1e0e4a37051ef54a1e59c Maintainer: shein Status: ready -->
<!-- Reviewed: no -->
<!-- $Revision$ -->
<!-- EN-Revision: n/a Maintainer: young Status: ready -->
<chapter xml:id="features.file-upload" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title> Загрузка файлов на сервер</title>
<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 способен принимать файл загружаемый при помощи любого
браузера, поддерживающего стандарт RFC-1867 (в том числе
<productname>Netscape Navigator 3</productname> и выше,
<productname>Microsoft Internet Explorer 3</productname>
с патчем от Microsoft или более поздние версии без патча).
Это дает возможность загружать как текстовые, так и бинарные
файлы. Вместе с PHP-аутентификацией и функциями
для работы с файловой системой вы получаете полный контроль над тем,
кому разрешено загружать файлы, и над тем, что делать с файлом после
его загрузки.
Данная возможность позволяет загружать как текстовые, так и
бинарные файлы. С помощью PHP-функций авторизации и манипуляции
файлайми вы получаете полный контроль над тем, кому разрешено
загружать файлы и что должно быть сделано после их загрузки.
</simpara>
<simpara>
PHP способен получать загруженные файлы из любого браузера,
совместимого со стандартом RFC-1867.
</simpara>
<note>
<title>Смежные замечания по конфигурации</title>
<para>
Также ознакомьтесь с описанием директив <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.max-input-time">max_input_time</link> и
<link linkend="ini.post-max-size">post_max_size</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> конфигурационного
файла &php.ini;
</para>
</note>
<para>
Также следует заметить, что PHP поддерживает загрузку файлов методом PUT,
который используется в клиентах <productname>Netscape Composer</productname>
и W3C <productname>Amaya</productname>. Для получения
и W3C <productname>Amaya</productname>. Для получения
более детальной документации обратитесь к разделу
<link linkend="features.file-upload.put-method">поддержка метода PUT</link>
</para>
<para>
Страница для загрузки файлов может быть реализована при помощи
специальной формы, которая выглядит примерно так:
</para>
<para>
<example>
<title>Форма для загрузки файлов</title>
<para>
Страница для загрузки файлов может быть реализована при помощи
специальной формы, которая выглядит примерно так:
</para>
<programlisting role="html">
<![CDATA[
<form enctype="multipart/form-data" action="_URL_" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
Отправить этот файл: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
<!-- Тип кодирования данных, 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="Send File" />
</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>
В приведенном выше примере "_URL_" необходимо заменить ссылкой
на PHP-скрипт. Скрытое поле <literal>MAX_FILE_SIZE</literal>(значение необходимо
указывать в байтах) должно предшествовать полю для выбора файла,
и его значение является максимально допустимым размером принимаемого
файла. Также следует убедиться, что в атрибутах формы вы указали
<literal>enctype="multipart/form-data"</literal>, в противном случае
загрузка файлов на сервер выполняться не будет.
<warning>
<para>
Опция <literal>MAX_FILE_SIZE</literal> является рекомендацией браузеру, даже если
бы PHP также проверял это условие. Обойти это ограничение на
стороне браузера достаточно просто, следовательно, вы не должны
полагаться на то, что все файлы большего размера будут блокированы
при помощи этой возможности. Тем не менее, ограничение PHP касательно
максимального размера обойти невозможно. Вы в любом случае должны
добавлять переменную формы <literal>MAX_FILE_SIZE</literal>, так как она предотвращает
тревожное ожидание пользователей при передаче огромных файлов, только
для того, чтобы узнать, что файл слишком большой и передача фактически
не состоялась.
</para>
</warning>
Суперглобальный массив <varname>$_FILES</varname> доступен
начиная с PHP 4.1.0 (В более ранних версиях используйте вместо
него <varname>$HTTP_POST_FILES</varname>).
Эти массивы будут содержать всю информацию о загруженных файлах.
</para>
<para>
Переменные, определенные для загруженных файлов, зависят от
версии PHP и текущей конфигурации. Суперглобальный массив
<link linkend="reserved.variables.files">$_FILES</link>
доступен начиная с PHP 4.1.0. Массив <varname>$HTTP_POST_FILES</varname>
доступен начиная с PHP 4.0.0. Эти массивы содержат всю информацию
о загруженных файлах. Использование <varname>$_FILES</varname>
является более предпочтительным.
В случае, если конфигурационная директива <link linkend="ini.register-globals">register_globals</link>
установлена значением <emphasis>on</emphasis>, дополнительно будут объявлены переменные с соответствующими именами.
Начиная с версии <link xlink:href="&url.php.release4.2.0;">4.2.0</link> значением
по умолчанию для опции <link linkend="ini.register-globals">register_globals</link>
является <emphasis>off</emphasis>.
</para>
<para>
Содержимое массива <link linkend="reserved.variables.files">$_FILES</link>
для нашего примера приведено ниже. Обратите внимание, что здесь предполагается
использование имени <emphasis>userfile</emphasis> для поля выбора файла, как и
в приведенном выше примере. На самом деле имя поля может быть любым.
Содержимое массива <varname>$_FILES</varname> для нашего примера
приведено ниже. Обратите внимание, что здесь предполагается
использование имени <emphasis>userfile</emphasis> для поля
выбора файла, как и в приведенном выше примере. На самом деле
имя поля может быть любым.
<variablelist>
<varlistentry>
<term><varname>$_FILES['userfile']['name']</varname></term>
@ -112,8 +116,10 @@
<listitem>
<para>
Mime-тип файла, в случае, если браузер предоставил такую
информацию. Пример: <literal>"image/gif"</literal>.
</para>
информацию. Пример: <literal>"image/gif"</literal>. Этот
mime-тип не проверяется в PHP, так что не полагайтесь
на его значение без проверки.
</para>
</listitem>
</varlistentry>
<varlistentry>
@ -136,46 +142,29 @@
<term><varname>$_FILES['userfile']['error']</varname></term>
<listitem>
<para>
<link linkend="features.file-upload.errors">Код ошибки</link>, которая
может возникнуть при загрузке файла. Ключ <emphasis>['error']</emphasis>
<link linkend="features.file-upload.errors">Код ошибки</link>,
которая может возникнуть при загрузке файла. Этот элемент
был добавлен в PHP 4.2.0
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<note>
<para>
В PHP 4.1.0 и более ранних версиях описанный выше массив назывался
<varname>$HTTP_POST_FILES</varname> и не являлся
<link linkend="language.variables.superglobals">суперглобальным</link>,
в отличие от <varname>$_FILES</varname>. В PHP 3 массив
<varname>$HTTP_POST_FILES</varname> не определен.
</para>
</note>
<para>
В случае, если <link linkend="ini.register-globals">register_globals</link>
установлена значением <emphasis>on</emphasis> в конфигурационном
файле &php.ini;, будут доступны дополнительные переменные. Например,
<varname>$userfile_name</varname> будет эквивалентна переменной <varname>$_FILES['userfile']['name']</varname>,
а <varname>$userfile_type</varname> соответствует <varname>$_FILES['userfile']['type']</varname>, и так далее.
Не стоит забывать, что начиная с PHP 4.2.0 для директивы register_globals
значение по умолчанию <emphasis>off</emphasis>. Рекомендуется не полагаться на значение этой директивы.
</para>
<para>
По умолчанию принятые файлы сохраняются на сервере в стандартной
временной папке до тех пор, пока не будет задана другая директория при
помощи директивы <link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>
конфигурационного файла &php.ini;. Директорию сервера по умолчанию
можно сменить, установив переменную <envar>TMPDIR</envar> для
окружения, в котором выполняется PHP. Установка переменной <envar>TMPDIR</envar> при помощи
окружения, в котором выполняется PHP. Установка этой переменной при помощи
функции <function>putenv</function> внутри PHP-скрипта работать
не будет. Эта переменная окружения также может использоваться для того,
чтобы удостовериться, что другие операции также работают с принятыми файлами.
<example>
<title>Проверка загружаемых на сервер файлов</title>
<para>
Для получения более детальной информации вы можете ознакомится
Для получения более детальной информации вы можете ознакомиться
с описанием функций <function>is_uploaded_file</function>
и <function>move_uploaded_file</function>. Следующий пример
принимает и обрабатывает загруженный при помощи формы файл.
@ -189,16 +178,16 @@
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
print "<pre>";
echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
print "File is valid, and was successfully uploaded. ";
print "Here's some more debugging info:\n";
print_r($_FILES);
echo "Файл корректен и был успешно загружен.\n";
} else {
print "Possible file upload attack! Here's some debugging info:\n";
print "Possible file upload attack! Дополнительная отладочная информация:\n";
print_r($_FILES);
echo "Возможная атака с помощью файловой загрузки!\n";
}
echo 'Некоторая отладочная информация:';
print_r($_FILES);
print "</pre>";
?>
@ -213,9 +202,11 @@ print "</pre>";
чтобы отсечь слишком большие или слишком маленькие файлы. Также вы
можете использовать переменную <varname>$_FILES['userfile']['type']</varname>
для исключения файлов, которые не удовлетворяют критерию касательно
типа файла. Начиная с PHP 4.2.0 вы можете использовать
типа файла, однако, принимайте во внимание, что это поле полностью
контролируется клиентом, используйте его только в качестве первой
из серии проверок. Начиная с PHP 4.2.0, вы можете использовать
<varname>$_FILES['userfile']['error']</varname> и <link
linkend="features.file-upload.errors">разъяснение сообщений об ошибках</link>
linkend="features.file-upload.errors">коды ошибок</link>
при реализации вашей логики. Независимо от того, какую модель поведения
вы выбрали, вы должны удалить файл из временной папки или переместить его в
другую директорию.
@ -228,17 +219,53 @@ print "</pre>";
</simpara>
<simpara>
По окончанию работы скрипта, в случае, если принятый файл не был
переименован, или перемещен он будет автоматически удален из временной папки.
переименован или перемещен, он будет автоматически удален из временной папки.
</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];
$name = $_FILES["pictures"]["name"][$key];
move_uploaded_file($tmp_name, "data/$name");
}
}
?>
]]>
</programlisting>
</example>
<para>
Полоса прогресса загрузки файлов может быть реализована с помощью <link
linkend="ini.apc.rfc1867">apc.rfc1867</link>.
</para>
</sect1>
<sect1 xml:id="features.file-upload.errors">
<title>Разъяснение сообщений об ошибках</title>
<simpara>
Начиная с PHP 4.2.0, PHP возвращает код ошибки наряду с другими
атрибутами принятого файла. Он расположен в массиве, создаваемом PHP
атрибутами принятого файла. Он расположен в массиве, создаваемом PHP
при загрузке файла, и может быть получен при обращении по ключу
<emphasis>['error']</emphasis>. Говоря другими словами, код ошибки можно
<literal>error</literal>. Говоря другими словами, код ошибки можно
найти в переменной <varname>$_FILES['userfile']['error']</varname>.
</simpara>
<para>
@ -247,7 +274,7 @@ print "</pre>";
<term><constant>UPLOAD_ERR_OK</constant></term>
<listitem>
<para>
Значение: 0; Ошибок не возникало, файл был успешно загружен на сервер.
Значение: 0; Ошибок не возникло, файл был успешно загружен на сервер.
</para>
</listitem>
</varlistentry>
@ -286,6 +313,34 @@ print "</pre>";
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><constant>UPLOAD_ERR_NO_TMP_DIR</constant></term>
<listitem>
<para>
Значение: 6; Отсутствует временная папка. Добавлено в PHP 4.3.10 и PHP
5.0.3.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><constant>UPLOAD_ERR_CANT_WRITE</constant></term>
<listitem>
<para>
Значение: 7; Не удалось записать файл на диск. Добавлено в PHP 5.1.0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><constant>UPLOAD_ERR_EXTENSION</constant></term>
<listitem>
<para>
Значение: 8; PHP-расширение остановило загрузку файла. PHP не
предоставляет способа определить какое расширение остановило
загрузку файла; в этом может помочь просмотр списка загруженных
расширений из phpinfo(). Добавлено в PHP 5.2.0.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<note>
@ -300,11 +355,11 @@ print "</pre>";
<simpara>
Опция <literal>MAX_FILE_SIZE</literal> не должна позволять передачу файлов,
размер которых превышает лимит, установленный конфигурационной директивой
<link linkend="ini.upload-max-filesize">upload_max_filesize</link>.
<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>
достаточно велико.
@ -328,19 +383,30 @@ print "</pre>";
</simpara>
</note>
<warning>
<simpara>
Директива <link linkend="ini.max-input-time">max_input_time</link> указывает
максимально допустимое время в секундах для получения входящих данных,
в том числе и загружаемых файлов. В случае, если вы имеете дело с несколькими
или большими файлами, либо удаленные пользователи используют медленный
канал, ограничение по умолчанию в <literal>60 секунд</literal> может быть превышено.
</simpara>
</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> достаточно велико.
слишком мала, большие файлы не смогут быть загружены на сервер.
Убедитесь, что значение директивы <literal>post_max_size</literal> достаточно велико.
</simpara>
<simpara>
Начиная с версии PHP 5.2.12, опция
<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>
Если не проверять, с какими файлами вы работаете, пользователи могут
@ -348,19 +414,22 @@ print "</pre>";
директориях.
</simpara>
<simpara>
Следут заметить, что <productname>CERN httpd</productname> может отсечь все, что идет после первого
пробела в получаемом от клиента заголовке content-type. Если у вас именно
такой случай, <productname>CERN httpd</productname> не будет поддерживать возможность загрузки файлов.
Следут заметить, что <productname>CERN httpd</productname> может
отсечь все, что идет после первого пробела в получаемом от
клиента заголовке content-type. Если у вас именно такой случай,
<productname>CERN httpd</productname> не сможет корректно
загрузить файлы.
</simpara>
<simpara>
Поскольку разные системы по-разному работают с файловой структурой,
у вас нет никаких гарантий того, что файлы с экзотическими именами
нет никаких гарантий того, что файлы с экзотическими именами
(например, которые содержат пробельные символы) будут обработаны корректно.
</simpara>
<simpara>
Разработчики не должны использовать одинаковые имена для полей ввода и полей
Разработчики не должны использовать одинаковые имена для
обычных полей ввода (тег <literal>input</literal>) и полей
выбора файла в пределах одной и той же формы (например, используя имя
вида <literal>foo[]</literal>).
для тега <literal>input</literal> наподобие <literal>foo[]</literal>).
</simpara>
</sect1>
@ -371,17 +440,11 @@ print "</pre>";
различные значения <literal>name</literal> для тега <literal>input</literal>.
</simpara>
<simpara>
Также предусмотрена возможность автоматического получения организованной в
массив информации о нескольких одновременно загружаемых файлах.
Также можно одновременно загружать несколько файлов и
автоматически получить их в виде массива.
Для реализации такой возможности используйте тот же синтаксис отправки
массива из HTML-формы, что и для множественных полей
<literal>select</literal> и <literal>checkbox</literal>:
массива из HTML-формы, что и для множественных полей select и checkbox:
</simpara>
<note>
<para>
Поддержка загрузки нескольких файлов была добавлена в PHP 3.0.10.
</para>
</note>
<para>
<example>
<title>Загрузка нескольких файлов</title>
@ -403,8 +466,8 @@ print "</pre>";
<varname>$_FILES['userfile']['name']</varname>, и
<varname>$_FILES['userfile']['size']</varname> будут
инициализированы (точно так же, как и <varname>$HTTP_POST_FILES</varname>
для PHP 4.1.0 и более ранних версий). Если конфигурационная директива
<link linkend="ini.register-globals">register_globals</link> установлена значением <literal>on</literal>,
для PHP 4.1.0 и более ранних версий). Если включена конфигурационная директива
<link linkend="ini.register-globals">register_globals</link>,
также будут инициализированы сопутствующие глобальные переменные.
Каждая из таких переменных будет представлять собой численно индексированный
массив соответствующих значений для принятых файлов.
@ -427,29 +490,84 @@ print "</pre>";
<varname>$_FILES['userfile']['type'][0]</varname> также будут
инициализированы.
</simpara>
<warning>
<simpara>
Начиная с версии PHP 5.2.12, конфигурационная директива
<link linkend="ini.max-file-uploads">max_file_uploads</link>
регулирует лимит одновременно загружаемых файлов в течение одного
запроса. Вам необходимо будет убедиться, что ваша форма
не пытается загрузить файлов больше этого лимита за один запрос.
</simpara>
</warning>
</sect1>
<sect1 xml:id="features.file-upload.put-method">
<title>Поддержка метода PUT</title>
<para>
PHP поддерживает загрузку файлов методом HTTP PUT, который
используется в некоторых клиентах для загрузки файлов на сервер.
Запросы PUT намного проще, чем обыкновенная POST загрузка файла на
сервер и выглядят примерно так:
<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>.
Как правило, эта директива расположена внутри блока
<literal>&lt;Directory&gt;</literal> или же внутри блока
<literal>&lt;VirtualHost&gt;</literal>. Сама запись выглядит
следующим образом:
<informalexample>
<programlisting>
<![CDATA[
Script PUT /put.php
]]>
</programlisting>
</informalexample>
</para>
<simpara>
Поддержка метода PUT была изменена при переходе от PHP 3 к PHP 4.
В PHP 4 вы должны использовать стандартный поток ввода для чтения
файла, передаваемого методом HTTP PUT.
Это указывает веб-серверу Apache на необходимость перенаправлять
все PUT-запросы, контекст которых совпадает с контекстом, в
которым вы разместили эту строку, в файл <filename>put.php</filename>.
Предполагается, что файлы с расширением <filename>.php</filename>
обрабатываются, как PHP-скрипты, и что сам PHP установлен и работает.
Ресурсом назначения для всех PUT-запросов на этот скрипт должен быть
сам скрипт, а не имя файла, которое должен иметь загружаемый файл.
</simpara>
<simpara>
Внутри вашего файла put.php file вы можете поместить что-нибудь похожее на
следующий пример. Он скопирует содержимое загруженного файла в
файл <filename>myputfile.ext</filename> на сервер. Возможно,
вам понадобится осуществить несколько проверок и/или авторизовать
пользователя перед выполнением копирования этого файла.
</simpara>
<para>
<example>
<title>Сохранение загруженного при помощи HTTP PUT файла в PHP 4</title>
<title>Saving HTTP PUT files</title>
<programlisting role="php">
<![CDATA[
<?php
/* Данные PUT находятся в потоке stdin */
$putdata = fopen("php://stdin", "r");
/* PUT данные приходят в потоке ввода stdin */
$putdata = fopen("php://input", "r");
/* Открываем файл для записи */
/* Открываем файл на чтение */
$fp = fopen("myputfile.ext", "w");
/* Читаем данные блоками размером в 1 KB и
записываем их в файл */
/* Читаем 1 KB данных за один раз
и пишем в файл */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
@ -461,71 +579,6 @@ fclose($putdata);
</programlisting>
</example>
</para>
<note>
<para>
Вся документация, приведенная ниже, касается исключительно PHP 3.
</para>
</note>
<para>
PHP поддерживает загрузку файлов методом HTTP PUT, который используется в клиентах
<productname>Netscape Composer</productname> и
<productname>W3C Amaya</productname>. Запрос PUT выглядит проще,
чем в случае обыкновенной загрузки файла на сервер:
<informalexample>
<programlisting>
PUT /path/filename.html HTTP/1.1
</programlisting>
</informalexample>
</para>
<para>
Такой вызов означает, что удаленный клиент хотел бы сохранить
файл под именем <filename>/path/filename.html</filename> в дереве каталогов вашего веб-сервера.
Очевидно, что возможность клиента автоматически перезаписывать файлы вашего
веб-сервера при помощи Apache или PHP не является хорошим решением.
Поэтому для того, чтобы обрабатывать такие запросы, вам необходимо указать
веб-серверу PHP-скрипт, которому вы доверяете их обработку.
В веб-сервере Apache вы можете сделать это, используя директиву
<emphasis>Script</emphasis>. Она может находиться практически
в любом месте конфигурационного файла Apache. Как правило, эта директива
расположена внутри блока &lt;Directory&gt; или же внутри блока
&lt;Virtualhost&gt;. Сама запись выглядит следующим образом:
<informalexample>
<programlisting>
Script PUT /put.php
</programlisting>
</informalexample>
</para>
<simpara>
Это указывает веб-серверу Apache на необходимость перенаправлять по
указанному адресу все PUT-запросы, контекст которых совпадает с контекстом, в
которым вы разместили эту строку. Предполагается, что файлы с расширением .php
обрабатываются, как PHP-скрипты, и что сам PHP установлен и работает.
</simpara>
<simpara>
Внутри вашего файла put.php file вы можете поместить что-нибудь похожее на это:
</simpara>
<para>
<informalexample><programlisting role="php">
<![CDATA[
<?php copy($PHP_UPLOADED_FILE_NAME, $DOCUMENT_ROOT . $REQUEST_URI); ?>
]]>
</programlisting></informalexample>
</para>
<simpara>
Приведенный код скопирует файл в место, запрошенное клиентом. Возможно,
вы захотите выполнить какую-либо проверку и/или аутентифицировать
пользователя, прежде чем выполнять копирование. Трюк состоит в том, что
когда PHP видит PUT-запрос, он сохраняет полученный файл во временной
папке, как и при <link linkend="features.file-upload.post-method">загрузке методом POST</link>.
По окончании обработки запроса временный файл удаляется.
Поэтому ваш PHP-скрипт, обрабатывающий PUT-запрос, должен скопировать куда-либо
полученный файл. Имя временного файла хранится в переменной
<varname>$PHP_PUT_FILENAME</varname>, а предполагаемое имя файла можно найти в
переменной <varname>$REQUEST_URI</varname> (может быть другим на веб-серверах, отличных от Apache).
Запрашиваемое имя файла указывается удаленным клиентом. Вы не обязаны
следовать его указаниям. Например, вы можете скопировать все загруженные
файлы в отдельный каталог.
</simpara>
</sect1>
</chapter>
@ -541,7 +594,7 @@ sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil