1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.controller.request">
4 <title>Объект запроса</title>
5 <sect2 id="zend.controller.request.introduction">
6 <title>Введение</title>
8 Объект запроса - это простой "объект значений"
9 (<ulink url="http://www.patternsforphp.com/wiki/Value_Object">value
10 object</ulink>), который передается между
11 <classname>Zend_Controller_Front</classname>, маршрутизатором,
12 диспетчером и контроллерами. Он хранит в себе имена запрошенных
13 модуля, контроллера, действия и необязательные параметры, а также
14 остальную среду (переменные) запроса, будь это HTTP, CLI или
20 Доступ к имени модуля производится через
21 <code>getModuleName()</code> и <code>setModuleName()</code>.
25 Доступ к имени контроллера производится через
26 <code>getControllerName()</code> и
27 <code>setControllerName()</code>.
31 Доступ к имени действия производится через
32 <code>getActionName()</code> и
33 <code>setActionName()</code>.
37 Параметры, доступные через действие, являются ассоциативным
38 массивом пар ключ/значение, который извлекается целиком через
39 метод <code>getParams()</code> и устанавливается через метод
40 <code>setParams()</code>. Его элементы можно извлекать и
41 устанавливать по отдельности через те же методы
42 <code>getParam()</code> и <code>setParam()</code>
48 Методов, которые можно использовать в запросе, может быть больше, в
49 зависимости от типа запроса. Например, используемый по умолчанию
50 запрос <classname>Zend_Controller_Request_Http</classname> имеет методы для
51 получения URI запроса, пути в нем, параметров <varname>$_GET</varname> и
52 <varname>$_POST</varname>, и т.д.
56 Объект запроса передается фронт-контроллеру, либо инициализируется в
57 начале процесса диспетчеризации до того, как будет произведена
58 маршрутизация. Он передается всем объектам в цепочке
63 Кроме того, объект запроса очень полезен в тестировании.
64 Разработчик может вручную установить переменные запроса, включая
65 модуль, контроллер, действие, параметры, URI и т.д., и передать
66 объект запроса фронт-контроллеру для проверки процесса выполнения
67 приложения. Если комбинировать его с
68 <link linkend="zend.controller.response">объектом ответа</link>,
69 то становится возможным тщательное и точное юнит-тестирование
74 <sect2 id="zend.controller.request.http">
75 <title>HTTP-запросы</title>
77 <sect3 id="zend.controller.request.http.dataacess">
78 <title>Доступ к данным запроса</title>
81 <classname>Zend_Controller_Request_Http</classname> инкапсулирует доступ к
82 соответствующим значениям, таким, как имя и значение ключа для
83 переменных контроллера и действия, и все дополнительные
84 параметры, полученные из URI. Он также позволяет обращаться
85 к значениям, содержащимся в суперглобальных массивах, как к
86 своим открытым членам, и управляет текущими базовым URL и URI
87 запроса. Суперглобальные значения не могут устанавливаться в
88 объекте запроса, вместо этого используйте методы
89 setParam/getParam для установки или получения пользовательских
94 <title>Суперглобальные данные</title>
96 Когда получаете доступ к суперглобальным данным через
97 <classname>Zend_Controller_Request_Http</classname> как к публичным
98 свойствам, то необходимо помнить, что имя свойства (ключ
99 суперглобального массива) сопоставляются с суперглобальными
100 массивами в определенной последовательности: 1. GET,
101 2. POST, 3. COOKIE, 4. SERVER, 5. ENV.
106 Отдельные значения из суперглобальных массивов можно также
107 получить через открытые методы. Например, необработанное
108 значение <varname>$_POST['user']</varname> может быть получено через
109 вызов метода <code>getPost('user')</code> объекта запроса. Эти
110 методы включают в себя <code>getQuery()</code> для получения
111 элементов массива <varname>$_GET</varname> и <code>getHeader()</code>
112 для получения заголовков запроса.
116 <title>Данные GET и POST</title>
118 Будьте осторожны, когда извлекаете данные из объекта
119 запроса, поскольку они совсем не фильтруются. Маршрутизатор
120 и диспетчер производят проверку на допустимость и фильтрацию
121 данных для использования в своих целях, но оставляют их
122 нетронутыми в объекте запроса.
127 <title>Извлечение Raw POST данных</title>
130 Начиная с версии 1.5.0 вы можете также извлекать данные POST
131 в том виде, в котором они присутствуют в теле запроса,
132 используя метод <code>getRawPost()</code>. Этот метод
133 возвращает false, если данные POST отсутствуют в теле
134 запроса, иначе - все тело POST.
138 Этот метод в основном полезен для получения содержимого при
139 разработке RESTful приложений.
144 Вы можете также устанавливать пользовательские параметры в
145 объекте запроса, используя <code>setParam()</code>, и извлекать
146 их после, используя <code>getParam()</code>. Маршрутизатор
147 использует этот функционал для установки параметров,
148 обнаруженных в URI запроса, в объекте запроса.
152 <title>getParam() извлекает не только пользовательские
156 <code>getParam()</code> извлекает значения из нескольких
157 источников. В порядке следования эти источники включают в
158 себя: установленные через метод <code>setParam()</code>
159 пользовательские параметры, параметры
160 <code>GET</code>, и, наконец, параметры <code>POST</code>.
161 Помните об этом, когда извлекаете данные через этот метод.
165 Если вы хотите извлекать только те параметры, которые
166 установили через <code>setParam()</code>, то используйте
167 <code>getUserParam()</code>.
171 Кроме этого, начиная с версии 1.5.0, вы можете ограничивать
172 набор доступных для поиска источников параметров.
173 <code>setParamSources()</code> позволяет указывать
174 пустой массив или массив с одним или более значений, это
175 могут быть'_GET' и '_POST' (по умолчанию оба разрешены).
176 Через этот массив задается набор источников параметров,
177 которым можно пользоваться для поиска. Если вы хотите
178 ограничить доступ источником '_GET', то указывайте
179 <code>setParamSources(array('_GET'))</code>.
184 <title>Причуды Apache</title>
186 Если вы используете обработчик ошибок 404 веб-сервера Apache
187 для передачи приходящих запросов фронт-контроллеру или
188 используете флаг PT с правилами перезаписи, то нужный вам
189 URI будет содержаться в
190 <varname>$_SERVER['REDIRECT_URL']</varname>, а не в
191 <varname>$_SERVER['REQUEST_URI']</varname>. Если вы используете
192 такие установки и получаете неверную маршрутизацию, то
193 должны использовать для своего объекта запроса класс
194 <classname>Zend_Controller_Request_Apache404</classname> вместо
195 <classname>Zend_Controller_Request_Http</classname>, используемого по
199 <programlisting language="php"><![CDATA[
200 $request = new Zend_Controller_Request_Apache404();
201 $front->setRequest($request);
206 <classname>Zend_Controller_Request_Http</classname> и просто изменяет
207 автоопределение URI запроса. Он может использоваться в
214 <sect3 id="zend.controller.request.http.baseurl">
215 <title>Базовый URL и поддиректории</title>
218 <classname>Zend_Controller_Request_Http</classname> позволяет использовать
219 <classname>Zend_Controller_Router_Rewrite</classname> в поддиректориях.
220 <classname>Zend_Controller_Request_Http</classname> попытается автоматически
221 определить ваш базовый URL и соответствующим образом установить
226 Например, если вы храните ваш <code>index.php</code> в
227 поддиректории <code>/projects/myapp/index.php</code>
228 веб-сервера, то базовый URL (основа перезаписи) должен быть
229 установлен в <code>/projects/myapp</code>. Эта строка будет
230 удаляться из начала пути до того, как будут производиться поиск
231 соответствующего маршрута.
232 Это освобождает от необходимости ее указания в начале каждого
233 маршрута. Маршрут <code>'user/:username'</code> будет
234 соответствовать URI вида
235 <code>http://localhost/projects/myapp/user/martel</code> и
236 <code>http://example.com/user/martel</code>.
240 <title>Определение URL чувствительно к регистру</title>
242 Автоматическое определение базового URL чувствительно к
243 регистру, поэтому убедитесь, что ваш URL соответствует имени
244 поддиректории в файловой системе (даже на платформе
245 Windows). Если не соответствует, то будет сгенерировано
251 Если базовый URL определяется некорректно, то вы можете заменить
252 его своим базовым путем с помощью метода
253 <code>setBaseUrl()</code>, который есть в классах
254 <classname>Zend_Http_Request</classname>,
255 <classname>Zend_Controller_Request_Http</classname> и
256 <classname>Zend_Controller_Front</classname>. Легче всего установить его
257 через <classname>Zend_Controller_Front</classname>, который в свою очередь
258 установит его в объекте запроса. Пример установки своего
262 <programlisting language="php"><![CDATA[
264 * Обработка запроса со своим базовым URL через Zend_Controller_Front
266 $router = new Zend_Controller_Router_Rewrite();
267 $controller = Zend_Controller_Front::getInstance();
268 $controller->setControllerDirectory('./application/controllers')
270 ->setBaseUrl('/projects/myapp'); // установка базового URL!
271 $response = $controller->dispatch();
276 <sect3 id="zend.controller.request.http.method">
277 <title>Определение HTTP-метода запроса</title>
280 <code>getMethod()</code> позволяет определить HTTP-метод
281 текущего запроса. Кроме этого, есть набор методов, позволяющий
282 проверить, использовался ли тот или иной HTTP-метод
283 при произведении текущего запроса. Все они возвращают ответ булевого типа:
287 <listitem><para><code>isGet()</code></para></listitem>
288 <listitem><para><code>isPost()</code></para></listitem>
289 <listitem><para><code>isPut()</code></para></listitem>
290 <listitem><para><code>isDelete()</code></para></listitem>
291 <listitem><para><code>isHead()</code></para></listitem>
292 <listitem><para><code>isOptions()</code></para></listitem>
296 Эти методы могут использоваться в основном для создания т.н.
301 <sect3 id="zend.controller.request.http.ajax">
302 <title>Определение запросов AJAX</title>
305 <classname>Zend_Controller_Request_Http</classname> имеет
307 для определения запросов AJAX: <code>isXmlHttpRequest()</code>.
308 Этот метод проверяет наличие заголовка HTTP-запроса
309 <code>X-Requested-With</code> со значением 'XMLHttpRequest'.
310 Если он найден, то возвращается <constant>TRUE</constant>.
314 На данный момент известно, что этот заголовок по умолчанию
315 отправляется следующими JS-библиотеками:
319 <listitem><para>Prototype/Scriptaculous (и библиотеки, производные от Prototype)</para></listitem>
320 <listitem><para>Yahoo! UI Library</para></listitem>
321 <listitem><para>jQuery</para></listitem>
322 <listitem><para>MochiKit</para></listitem>
326 Большинство AJAX-библиотек позволяет отправлять произвольные
327 заголовки HTTP-запросов. Если ваша библиотека не отправляет этот
328 заголовок, то просто добавьте его в качестве заголовка ответа,
329 чтобы быть уверенным в том, что метод
330 <code>isXmlHttpRequest()</code> работает в вашем случае.
335 <sect2 id="zend.controller.request.subclassing">
336 <title>Создание подклассов объекта запроса</title>
339 Базовый класс запроса, используемый для всех объектов запроса, -
340 абстрактный класс <classname>Zend_Controller_Request_Abstract</classname>.
341 Он определяет следующие методы:
344 <programlisting language="php"><![CDATA[
345 abstract class Zend_Controller_Request_Abstract
350 public function getControllerName();
353 * @param string $value
356 public function setControllerName($value);
361 public function getActionName();
364 * @param string $value
367 public function setActionName($value);
372 public function getControllerKey();
378 public function setControllerKey($key);
383 public function getActionKey();
389 public function setActionKey($key);
395 public function getParam($key);
399 * @param mixed $value
402 public function setParam($key, $value);
407 public function getParams();
410 * @param array $array
413 public function setParams(array $array);
416 * @param boolean $flag
419 public function setDispatched($flag = true);
424 public function isDispatched();
429 Объект запроса является контейнером для переменных запроса. Цепочке
430 контроллеров надо знать только то, как устанавливать и получать
431 контроллер, действие, опциональные параметры и флаг
432 диспетчеризации. По умолчанию объект запроса будет искать в своих
433 параметрах, используя ключи контроллера и действия, для определения
434 текущих контроллера и действия.
438 Расширяйте этот класс или один из его производных классов, если вам
439 нужен класс запроса, взаимодействующий с определенной средой для
440 получения данных, использующихся в упомянутых выше задачах.
441 Примерами могут быть <link
442 linkend="zend.controller.request.http">среда
443 HTTP</link>, среда CLI или PHP-GTK.