| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.controller.request">
- <title>Объект запроса</title>
- <sect2 id="zend.controller.request.introduction">
- <title>Введение</title>
- <para>
- Объект запроса - это простой "объект значений"
- (<ulink url="http://www.patternsforphp.com/wiki/Value_Object">value
- object</ulink>), который передается между
- <classname>Zend_Controller_Front</classname>, маршрутизатором,
- диспетчером и контроллерами. Он хранит в себе имена запрошенных
- модуля, контроллера, действия и необязательные параметры, а также
- остальную среду (переменные) запроса, будь это HTTP, CLI или
- PHP-GTK.
- </para>
- <itemizedlist>
- <listitem><para>
- Доступ к имени модуля производится через
- <code>getModuleName()</code> и <code>setModuleName()</code>.
- </para></listitem>
- <listitem><para>
- Доступ к имени контроллера производится через
- <code>getControllerName()</code> и
- <code>setControllerName()</code>.
- </para></listitem>
- <listitem><para>
- Доступ к имени действия производится через
- <code>getActionName()</code> и
- <code>setActionName()</code>.
- </para></listitem>
- <listitem><para>
- Параметры, доступные через действие, являются ассоциативным
- массивом пар ключ/значение, который извлекается целиком через
- метод <code>getParams()</code> и устанавливается через метод
- <code>setParams()</code>. Его элементы можно извлекать и
- устанавливать по отдельности через те же методы
- <code>getParam()</code> и <code>setParam()</code>
- соответственно.
- </para></listitem>
- </itemizedlist>
- <para>
- Методов, которые можно использовать в запросе, может быть больше, в
- зависимости от типа запроса. Например, используемый по умолчанию
- запрос <classname>Zend_Controller_Request_Http</classname> имеет методы для
- получения URI запроса, пути в нем, параметров <varname>$_GET</varname> и
- <varname>$_POST</varname>, и т.д.
- </para>
- <para>
- Объект запроса передается фронт-контроллеру, либо инициализируется в
- начале процесса диспетчеризации до того, как будет произведена
- маршрутизация. Он передается всем объектам в цепочке
- диспетчеризации.
- </para>
- <para>
- Кроме того, объект запроса очень полезен в тестировании.
- Разработчик может вручную установить переменные запроса, включая
- модуль, контроллер, действие, параметры, URI и т.д., и передать
- объект запроса фронт-контроллеру для проверки процесса выполнения
- приложения. Если комбинировать его с
- <link linkend="zend.controller.response">объектом ответа</link>,
- то становится возможным тщательное и точное юнит-тестирование
- приложений MVC.
- </para>
- </sect2>
- <sect2 id="zend.controller.request.http">
- <title>HTTP-запросы</title>
- <sect3 id="zend.controller.request.http.dataacess">
- <title>Доступ к данным запроса</title>
- <para>
- <classname>Zend_Controller_Request_Http</classname> инкапсулирует доступ к
- соответствующим значениям, таким, как имя и значение ключа для
- переменных контроллера и действия, и все дополнительные
- параметры, полученные из URI. Он также позволяет обращаться
- к значениям, содержащимся в суперглобальных массивах, как к
- своим открытым членам, и управляет текущими базовым URL и URI
- запроса. Суперглобальные значения не могут устанавливаться в
- объекте запроса, вместо этого используйте методы
- setParam/getParam для установки или получения пользовательских
- параметров.
- </para>
- <note>
- <title>Суперглобальные данные</title>
- <para>
- Когда получаете доступ к суперглобальным данным через
- <classname>Zend_Controller_Request_Http</classname> как к публичным
- свойствам, то необходимо помнить, что имя свойства (ключ
- суперглобального массива) сопоставляются с суперглобальными
- массивами в определенной последовательности: 1. GET,
- 2. POST, 3. COOKIE, 4. SERVER, 5. ENV.
- </para>
- </note>
- <para>
- Отдельные значения из суперглобальных массивов можно также
- получить через открытые методы. Например, необработанное
- значение <varname>$_POST['user']</varname> может быть получено через
- вызов метода <code>getPost('user')</code> объекта запроса. Эти
- методы включают в себя <code>getQuery()</code> для получения
- элементов массива <varname>$_GET</varname> и <code>getHeader()</code>
- для получения заголовков запроса.
- </para>
- <note>
- <title>Данные GET и POST</title>
- <para>
- Будьте осторожны, когда извлекаете данные из объекта
- запроса, поскольку они совсем не фильтруются. Маршрутизатор
- и диспетчер производят проверку на допустимость и фильтрацию
- данных для использования в своих целях, но оставляют их
- нетронутыми в объекте запроса.
- </para>
- </note>
- <note>
- <title>Извлечение Raw POST данных</title>
- <para>
- Начиная с версии 1.5.0 вы можете также извлекать данные POST
- в том виде, в котором они присутствуют в теле запроса,
- используя метод <code>getRawPost()</code>. Этот метод
- возвращает false, если данные POST отсутствуют в теле
- запроса, иначе - все тело POST.
- </para>
- <para>
- Этот метод в основном полезен для получения содержимого при
- разработке RESTful приложений.
- </para>
- </note>
- <para>
- Вы можете также устанавливать пользовательские параметры в
- объекте запроса, используя <code>setParam()</code>, и извлекать
- их после, используя <code>getParam()</code>. Маршрутизатор
- использует этот функционал для установки параметров,
- обнаруженных в URI запроса, в объекте запроса.
- </para>
- <note>
- <title>getParam() извлекает не только пользовательские
- параметры</title>
- <para>
- <code>getParam()</code> извлекает значения из нескольких
- источников. В порядке следования эти источники включают в
- себя: установленные через метод <code>setParam()</code>
- пользовательские параметры, параметры
- <code>GET</code>, и, наконец, параметры <code>POST</code>.
- Помните об этом, когда извлекаете данные через этот метод.
- </para>
- <para>
- Если вы хотите извлекать только те параметры, которые
- установили через <code>setParam()</code>, то используйте
- <code>getUserParam()</code>.
- </para>
- <para>
- Кроме этого, начиная с версии 1.5.0, вы можете ограничивать
- набор доступных для поиска источников параметров.
- <code>setParamSources()</code> позволяет указывать
- пустой массив или массив с одним или более значений, это
- могут быть'_GET' и '_POST' (по умолчанию оба разрешены).
- Через этот массив задается набор источников параметров,
- которым можно пользоваться для поиска. Если вы хотите
- ограничить доступ источником '_GET', то указывайте
- <code>setParamSources(array('_GET'))</code>.
- </para>
- </note>
- <note>
- <title>Причуды Apache</title>
- <para>
- Если вы используете обработчик ошибок 404 веб-сервера Apache
- для передачи приходящих запросов фронт-контроллеру или
- используете флаг PT с правилами перезаписи, то нужный вам
- URI будет содержаться в
- <varname>$_SERVER['REDIRECT_URL']</varname>, а не в
- <varname>$_SERVER['REQUEST_URI']</varname>. Если вы используете
- такие установки и получаете неверную маршрутизацию, то
- должны использовать для своего объекта запроса класс
- <classname>Zend_Controller_Request_Apache404</classname> вместо
- <classname>Zend_Controller_Request_Http</classname>, используемого по
- умолчанию.
- </para>
- <programlisting language="php"><![CDATA[
- $request = new Zend_Controller_Request_Apache404();
- $front->setRequest($request);
- ]]></programlisting>
- <para>
- Этот класс расширяет
- <classname>Zend_Controller_Request_Http</classname> и просто изменяет
- автоопределение URI запроса. Он может использоваться в
- качестве замены.
- </para>
- </note>
- </sect3>
- <sect3 id="zend.controller.request.http.baseurl">
- <title>Базовый URL и поддиректории</title>
- <para>
- <classname>Zend_Controller_Request_Http</classname> позволяет использовать
- <classname>Zend_Controller_Router_Rewrite</classname> в поддиректориях.
- <classname>Zend_Controller_Request_Http</classname> попытается автоматически
- определить ваш базовый URL и соответствующим образом установить
- его.
- </para>
- <para>
- Например, если вы храните ваш <code>index.php</code> в
- поддиректории <code>/projects/myapp/index.php</code>
- веб-сервера, то базовый URL (основа перезаписи) должен быть
- установлен в <code>/projects/myapp</code>. Эта строка будет
- удаляться из начала пути до того, как будут производиться поиск
- соответствующего маршрута.
- Это освобождает от необходимости ее указания в начале каждого
- маршрута. Маршрут <code>'user/:username'</code> будет
- соответствовать URI вида
- <code>http://localhost/projects/myapp/user/martel</code> и
- <code>http://example.com/user/martel</code>.
- </para>
- <note>
- <title>Определение URL чувствительно к регистру</title>
- <para>
- Автоматическое определение базового URL чувствительно к
- регистру, поэтому убедитесь, что ваш URL соответствует имени
- поддиректории в файловой системе (даже на платформе
- Windows). Если не соответствует, то будет сгенерировано
- исключение.
- </para>
- </note>
- <para>
- Если базовый URL определяется некорректно, то вы можете заменить
- его своим базовым путем с помощью метода
- <code>setBaseUrl()</code>, который есть в классах
- <classname>Zend_Http_Request</classname>,
- <classname>Zend_Controller_Request_Http</classname> и
- <classname>Zend_Controller_Front</classname>. Легче всего установить его
- через <classname>Zend_Controller_Front</classname>, который в свою очередь
- установит его в объекте запроса. Пример установки своего
- базового URL:
- </para>
- <programlisting language="php"><![CDATA[
- /**
- * Обработка запроса со своим базовым URL через Zend_Controller_Front
- */
- $router = new Zend_Controller_Router_Rewrite();
- $controller = Zend_Controller_Front::getInstance();
- $controller->setControllerDirectory('./application/controllers')
- ->setRouter($router)
- ->setBaseUrl('/projects/myapp'); // установка базового URL!
- $response = $controller->dispatch();
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.controller.request.http.method">
- <title>Определение HTTP-метода запроса</title>
- <para>
- <code>getMethod()</code> позволяет определить HTTP-метод
- текущего запроса. Кроме этого, есть набор методов, позволяющий
- проверить, использовался ли тот или иной HTTP-метод
- при произведении текущего запроса. Все они возвращают ответ булевого типа:
- </para>
- <itemizedlist>
- <listitem><para><code>isGet()</code></para></listitem>
- <listitem><para><code>isPost()</code></para></listitem>
- <listitem><para><code>isPut()</code></para></listitem>
- <listitem><para><code>isDelete()</code></para></listitem>
- <listitem><para><code>isHead()</code></para></listitem>
- <listitem><para><code>isOptions()</code></para></listitem>
- </itemizedlist>
- <para>
- Эти методы могут использоваться в основном для создания т.н.
- RESTful-архитектуры.
- </para>
- </sect3>
- <sect3 id="zend.controller.request.http.ajax">
- <title>Определение запросов AJAX</title>
- <para>
- <classname>Zend_Controller_Request_Http</classname> имеет
- рудиментарный метод
- для определения запросов AJAX: <code>isXmlHttpRequest()</code>.
- Этот метод проверяет наличие заголовка HTTP-запроса
- <code>X-Requested-With</code> со значением 'XMLHttpRequest'.
- Если он найден, то возвращается <constant>TRUE</constant>.
- </para>
- <para>
- На данный момент известно, что этот заголовок по умолчанию
- отправляется следующими JS-библиотеками:
- </para>
- <itemizedlist>
- <listitem><para>Prototype/Scriptaculous (и библиотеки, производные от Prototype)</para></listitem>
- <listitem><para>Yahoo! UI Library</para></listitem>
- <listitem><para>jQuery</para></listitem>
- <listitem><para>MochiKit</para></listitem>
- </itemizedlist>
- <para>
- Большинство AJAX-библиотек позволяет отправлять произвольные
- заголовки HTTP-запросов. Если ваша библиотека не отправляет этот
- заголовок, то просто добавьте его в качестве заголовка ответа,
- чтобы быть уверенным в том, что метод
- <code>isXmlHttpRequest()</code> работает в вашем случае.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.controller.request.subclassing">
- <title>Создание подклассов объекта запроса</title>
- <para>
- Базовый класс запроса, используемый для всех объектов запроса, -
- абстрактный класс <classname>Zend_Controller_Request_Abstract</classname>.
- Он определяет следующие методы:
- </para>
- <programlisting language="php"><![CDATA[
- abstract class Zend_Controller_Request_Abstract
- {
- /**
- * @return string
- */
- public function getControllerName();
- /**
- * @param string $value
- * @return self
- */
- public function setControllerName($value);
- /**
- * @return string
- */
- public function getActionName();
- /**
- * @param string $value
- * @return self
- */
- public function setActionName($value);
- /**
- * @return string
- */
- public function getControllerKey();
- /**
- * @param string $key
- * @return self
- */
- public function setControllerKey($key);
- /**
- * @return string
- */
- public function getActionKey();
- /**
- * @param string $key
- * @return self
- */
- public function setActionKey($key);
- /**
- * @param string $key
- * @return mixed
- */
- public function getParam($key);
- /**
- * @param string $key
- * @param mixed $value
- * @return self
- */
- public function setParam($key, $value);
- /**
- * @return array
- */
- public function getParams();
- /**
- * @param array $array
- * @return self
- */
- public function setParams(array $array);
- /**
- * @param boolean $flag
- * @return self
- */
- public function setDispatched($flag = true);
- /**
- * @return boolean
- */
- public function isDispatched();
- }
- ]]></programlisting>
- <para>
- Объект запроса является контейнером для переменных запроса. Цепочке
- контроллеров надо знать только то, как устанавливать и получать
- контроллер, действие, опциональные параметры и флаг
- диспетчеризации. По умолчанию объект запроса будет искать в своих
- параметрах, используя ключи контроллера и действия, для определения
- текущих контроллера и действия.
- </para>
- <para>
- Расширяйте этот класс или один из его производных классов, если вам
- нужен класс запроса, взаимодействующий с определенной средой для
- получения данных, использующихся в упомянутых выше задачах.
- Примерами могут быть <link
- linkend="zend.controller.request.http">среда
- HTTP</link>, среда CLI или PHP-GTK.
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|