Zend_Controller-Request.xml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.controller.request">
  4. <title>Объект запроса</title>
  5. <sect2 id="zend.controller.request.introduction">
  6. <title>Введение</title>
  7. <para>
  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 или
  15. PHP-GTK.
  16. </para>
  17. <itemizedlist>
  18. <listitem><para>
  19. Доступ к имени модуля производится через
  20. <code>getModuleName()</code> и <code>setModuleName()</code>.
  21. </para></listitem>
  22. <listitem><para>
  23. Доступ к имени контроллера производится через
  24. <code>getControllerName()</code> и
  25. <code>setControllerName()</code>.
  26. </para></listitem>
  27. <listitem><para>
  28. Доступ к имени действия производится через
  29. <code>getActionName()</code> и
  30. <code>setActionName()</code>.
  31. </para></listitem>
  32. <listitem><para>
  33. Параметры, доступные через действие, являются ассоциативным
  34. массивом пар ключ/значение, который извлекается целиком через
  35. метод <code>getParams()</code> и устанавливается через метод
  36. <code>setParams()</code>. Его элементы можно извлекать и
  37. устанавливать по отдельности через те же методы
  38. <code>getParam()</code> и <code>setParam()</code>
  39. соответственно.
  40. </para></listitem>
  41. </itemizedlist>
  42. <para>
  43. Методов, которые можно использовать в запросе, может быть больше, в
  44. зависимости от типа запроса. Например, используемый по умолчанию
  45. запрос <classname>Zend_Controller_Request_Http</classname> имеет методы для
  46. получения URI запроса, пути в нем, параметров <varname>$_GET</varname> и
  47. <varname>$_POST</varname>, и т.д.
  48. </para>
  49. <para>
  50. Объект запроса передается фронт-контроллеру, либо инициализируется в
  51. начале процесса диспетчеризации до того, как будет произведена
  52. маршрутизация. Он передается всем объектам в цепочке
  53. диспетчеризации.
  54. </para>
  55. <para>
  56. Кроме того, объект запроса очень полезен в тестировании.
  57. Разработчик может вручную установить переменные запроса, включая
  58. модуль, контроллер, действие, параметры, URI и т.д., и передать
  59. объект запроса фронт-контроллеру для проверки процесса выполнения
  60. приложения. Если комбинировать его с
  61. <link linkend="zend.controller.response">объектом ответа</link>,
  62. то становится возможным тщательное и точное юнит-тестирование
  63. приложений MVC.
  64. </para>
  65. </sect2>
  66. <sect2 id="zend.controller.request.http">
  67. <title>HTTP-запросы</title>
  68. <sect3 id="zend.controller.request.http.dataacess">
  69. <title>Доступ к данным запроса</title>
  70. <para>
  71. <classname>Zend_Controller_Request_Http</classname> инкапсулирует доступ к
  72. соответствующим значениям, таким, как имя и значение ключа для
  73. переменных контроллера и действия, и все дополнительные
  74. параметры, полученные из URI. Он также позволяет обращаться
  75. к значениям, содержащимся в суперглобальных массивах, как к
  76. своим открытым членам, и управляет текущими базовым URL и URI
  77. запроса. Суперглобальные значения не могут устанавливаться в
  78. объекте запроса, вместо этого используйте методы
  79. setParam/getParam для установки или получения пользовательских
  80. параметров.
  81. </para>
  82. <note>
  83. <title>Суперглобальные данные</title>
  84. <para>
  85. Когда получаете доступ к суперглобальным данным через
  86. <classname>Zend_Controller_Request_Http</classname> как к публичным
  87. свойствам, то необходимо помнить, что имя свойства (ключ
  88. суперглобального массива) сопоставляются с суперглобальными
  89. массивами в определенной последовательности: 1. GET,
  90. 2. POST, 3. COOKIE, 4. SERVER, 5. ENV.
  91. </para>
  92. </note>
  93. <para>
  94. Отдельные значения из суперглобальных массивов можно также
  95. получить через открытые методы. Например, необработанное
  96. значение <varname>$_POST['user']</varname> может быть получено через
  97. вызов метода <code>getPost('user')</code> объекта запроса. Эти
  98. методы включают в себя <code>getQuery()</code> для получения
  99. элементов массива <varname>$_GET</varname> и <code>getHeader()</code>
  100. для получения заголовков запроса.
  101. </para>
  102. <note>
  103. <title>Данные GET и POST</title>
  104. <para>
  105. Будьте осторожны, когда извлекаете данные из объекта
  106. запроса, поскольку они совсем не фильтруются. Маршрутизатор
  107. и диспетчер производят проверку на допустимость и фильтрацию
  108. данных для использования в своих целях, но оставляют их
  109. нетронутыми в объекте запроса.
  110. </para>
  111. </note>
  112. <note>
  113. <title>Извлечение Raw POST данных</title>
  114. <para>
  115. Начиная с версии 1.5.0 вы можете также извлекать данные POST
  116. в том виде, в котором они присутствуют в теле запроса,
  117. используя метод <code>getRawPost()</code>. Этот метод
  118. возвращает false, если данные POST отсутствуют в теле
  119. запроса, иначе - все тело POST.
  120. </para>
  121. <para>
  122. Этот метод в основном полезен для получения содержимого при
  123. разработке RESTful приложений.
  124. </para>
  125. </note>
  126. <para>
  127. Вы можете также устанавливать пользовательские параметры в
  128. объекте запроса, используя <code>setParam()</code>, и извлекать
  129. их после, используя <code>getParam()</code>. Маршрутизатор
  130. использует этот функционал для установки параметров,
  131. обнаруженных в URI запроса, в объекте запроса.
  132. </para>
  133. <note>
  134. <title>getParam() извлекает не только пользовательские
  135. параметры</title>
  136. <para>
  137. <code>getParam()</code> извлекает значения из нескольких
  138. источников. В порядке следования эти источники включают в
  139. себя: установленные через метод <code>setParam()</code>
  140. пользовательские параметры, параметры
  141. <code>GET</code>, и, наконец, параметры <code>POST</code>.
  142. Помните об этом, когда извлекаете данные через этот метод.
  143. </para>
  144. <para>
  145. Если вы хотите извлекать только те параметры, которые
  146. установили через <code>setParam()</code>, то используйте
  147. <code>getUserParam()</code>.
  148. </para>
  149. <para>
  150. Кроме этого, начиная с версии 1.5.0, вы можете ограничивать
  151. набор доступных для поиска источников параметров.
  152. <code>setParamSources()</code> позволяет указывать
  153. пустой массив или массив с одним или более значений, это
  154. могут быть'_GET' и '_POST' (по умолчанию оба разрешены).
  155. Через этот массив задается набор источников параметров,
  156. которым можно пользоваться для поиска. Если вы хотите
  157. ограничить доступ источником '_GET', то указывайте
  158. <code>setParamSources(array('_GET'))</code>.
  159. </para>
  160. </note>
  161. <note>
  162. <title>Причуды Apache</title>
  163. <para>
  164. Если вы используете обработчик ошибок 404 веб-сервера Apache
  165. для передачи приходящих запросов фронт-контроллеру или
  166. используете флаг PT с правилами перезаписи, то нужный вам
  167. URI будет содержаться в
  168. <varname>$_SERVER['REDIRECT_URL']</varname>, а не в
  169. <varname>$_SERVER['REQUEST_URI']</varname>. Если вы используете
  170. такие установки и получаете неверную маршрутизацию, то
  171. должны использовать для своего объекта запроса класс
  172. <classname>Zend_Controller_Request_Apache404</classname> вместо
  173. <classname>Zend_Controller_Request_Http</classname>, используемого по
  174. умолчанию.
  175. </para>
  176. <programlisting language="php"><![CDATA[
  177. $request = new Zend_Controller_Request_Apache404();
  178. $front->setRequest($request);
  179. ]]></programlisting>
  180. <para>
  181. Этот класс расширяет
  182. <classname>Zend_Controller_Request_Http</classname> и просто изменяет
  183. автоопределение URI запроса. Он может использоваться в
  184. качестве замены.
  185. </para>
  186. </note>
  187. </sect3>
  188. <sect3 id="zend.controller.request.http.baseurl">
  189. <title>Базовый URL и поддиректории</title>
  190. <para>
  191. <classname>Zend_Controller_Request_Http</classname> позволяет использовать
  192. <classname>Zend_Controller_Router_Rewrite</classname> в поддиректориях.
  193. <classname>Zend_Controller_Request_Http</classname> попытается автоматически
  194. определить ваш базовый URL и соответствующим образом установить
  195. его.
  196. </para>
  197. <para>
  198. Например, если вы храните ваш <code>index.php</code> в
  199. поддиректории <code>/projects/myapp/index.php</code>
  200. веб-сервера, то базовый URL (основа перезаписи) должен быть
  201. установлен в <code>/projects/myapp</code>. Эта строка будет
  202. удаляться из начала пути до того, как будут производиться поиск
  203. соответствующего маршрута.
  204. Это освобождает от необходимости ее указания в начале каждого
  205. маршрута. Маршрут <code>'user/:username'</code> будет
  206. соответствовать URI вида
  207. <code>http://localhost/projects/myapp/user/martel</code> и
  208. <code>http://example.com/user/martel</code>.
  209. </para>
  210. <note>
  211. <title>Определение URL чувствительно к регистру</title>
  212. <para>
  213. Автоматическое определение базового URL чувствительно к
  214. регистру, поэтому убедитесь, что ваш URL соответствует имени
  215. поддиректории в файловой системе (даже на платформе
  216. Windows). Если не соответствует, то будет сгенерировано
  217. исключение.
  218. </para>
  219. </note>
  220. <para>
  221. Если базовый URL определяется некорректно, то вы можете заменить
  222. его своим базовым путем с помощью метода
  223. <code>setBaseUrl()</code>, который есть в классах
  224. <classname>Zend_Http_Request</classname>,
  225. <classname>Zend_Controller_Request_Http</classname> и
  226. <classname>Zend_Controller_Front</classname>. Легче всего установить его
  227. через <classname>Zend_Controller_Front</classname>, который в свою очередь
  228. установит его в объекте запроса. Пример установки своего
  229. базового URL:
  230. </para>
  231. <programlisting language="php"><![CDATA[
  232. /**
  233. * Обработка запроса со своим базовым URL через Zend_Controller_Front
  234. */
  235. $router = new Zend_Controller_Router_Rewrite();
  236. $controller = Zend_Controller_Front::getInstance();
  237. $controller->setControllerDirectory('./application/controllers')
  238. ->setRouter($router)
  239. ->setBaseUrl('/projects/myapp'); // установка базового URL!
  240. $response = $controller->dispatch();
  241. ]]></programlisting>
  242. </sect3>
  243. <sect3 id="zend.controller.request.http.method">
  244. <title>Определение HTTP-метода запроса</title>
  245. <para>
  246. <code>getMethod()</code> позволяет определить HTTP-метод
  247. текущего запроса. Кроме этого, есть набор методов, позволяющий
  248. проверить, использовался ли тот или иной HTTP-метод
  249. при произведении текущего запроса. Все они возвращают ответ булевого типа:
  250. </para>
  251. <itemizedlist>
  252. <listitem><para><code>isGet()</code></para></listitem>
  253. <listitem><para><code>isPost()</code></para></listitem>
  254. <listitem><para><code>isPut()</code></para></listitem>
  255. <listitem><para><code>isDelete()</code></para></listitem>
  256. <listitem><para><code>isHead()</code></para></listitem>
  257. <listitem><para><code>isOptions()</code></para></listitem>
  258. </itemizedlist>
  259. <para>
  260. Эти методы могут использоваться в основном для создания т.н.
  261. RESTful-архитектуры.
  262. </para>
  263. </sect3>
  264. <sect3 id="zend.controller.request.http.ajax">
  265. <title>Определение запросов AJAX</title>
  266. <para>
  267. <classname>Zend_Controller_Request_Http</classname> имеет
  268. рудиментарный метод
  269. для определения запросов AJAX: <code>isXmlHttpRequest()</code>.
  270. Этот метод проверяет наличие заголовка HTTP-запроса
  271. <code>X-Requested-With</code> со значением 'XMLHttpRequest'.
  272. Если он найден, то возвращается <constant>TRUE</constant>.
  273. </para>
  274. <para>
  275. На данный момент известно, что этот заголовок по умолчанию
  276. отправляется следующими JS-библиотеками:
  277. </para>
  278. <itemizedlist>
  279. <listitem><para>Prototype/Scriptaculous (и библиотеки, производные от Prototype)</para></listitem>
  280. <listitem><para>Yahoo! UI Library</para></listitem>
  281. <listitem><para>jQuery</para></listitem>
  282. <listitem><para>MochiKit</para></listitem>
  283. </itemizedlist>
  284. <para>
  285. Большинство AJAX-библиотек позволяет отправлять произвольные
  286. заголовки HTTP-запросов. Если ваша библиотека не отправляет этот
  287. заголовок, то просто добавьте его в качестве заголовка ответа,
  288. чтобы быть уверенным в том, что метод
  289. <code>isXmlHttpRequest()</code> работает в вашем случае.
  290. </para>
  291. </sect3>
  292. </sect2>
  293. <sect2 id="zend.controller.request.subclassing">
  294. <title>Создание подклассов объекта запроса</title>
  295. <para>
  296. Базовый класс запроса, используемый для всех объектов запроса, -
  297. абстрактный класс <classname>Zend_Controller_Request_Abstract</classname>.
  298. Он определяет следующие методы:
  299. </para>
  300. <programlisting language="php"><![CDATA[
  301. abstract class Zend_Controller_Request_Abstract
  302. {
  303. /**
  304. * @return string
  305. */
  306. public function getControllerName();
  307. /**
  308. * @param string $value
  309. * @return self
  310. */
  311. public function setControllerName($value);
  312. /**
  313. * @return string
  314. */
  315. public function getActionName();
  316. /**
  317. * @param string $value
  318. * @return self
  319. */
  320. public function setActionName($value);
  321. /**
  322. * @return string
  323. */
  324. public function getControllerKey();
  325. /**
  326. * @param string $key
  327. * @return self
  328. */
  329. public function setControllerKey($key);
  330. /**
  331. * @return string
  332. */
  333. public function getActionKey();
  334. /**
  335. * @param string $key
  336. * @return self
  337. */
  338. public function setActionKey($key);
  339. /**
  340. * @param string $key
  341. * @return mixed
  342. */
  343. public function getParam($key);
  344. /**
  345. * @param string $key
  346. * @param mixed $value
  347. * @return self
  348. */
  349. public function setParam($key, $value);
  350. /**
  351. * @return array
  352. */
  353. public function getParams();
  354. /**
  355. * @param array $array
  356. * @return self
  357. */
  358. public function setParams(array $array);
  359. /**
  360. * @param boolean $flag
  361. * @return self
  362. */
  363. public function setDispatched($flag = true);
  364. /**
  365. * @return boolean
  366. */
  367. public function isDispatched();
  368. }
  369. ]]></programlisting>
  370. <para>
  371. Объект запроса является контейнером для переменных запроса. Цепочке
  372. контроллеров надо знать только то, как устанавливать и получать
  373. контроллер, действие, опциональные параметры и флаг
  374. диспетчеризации. По умолчанию объект запроса будет искать в своих
  375. параметрах, используя ключи контроллера и действия, для определения
  376. текущих контроллера и действия.
  377. </para>
  378. <para>
  379. Расширяйте этот класс или один из его производных классов, если вам
  380. нужен класс запроса, взаимодействующий с определенной средой для
  381. получения данных, использующихся в упомянутых выше задачах.
  382. Примерами могут быть <link
  383. linkend="zend.controller.request.http">среда
  384. HTTP</link>, среда CLI или PHP-GTK.
  385. </para>
  386. </sect2>
  387. </sect1>
  388. <!--
  389. vim:se ts=4 sw=4 et:
  390. -->