Zend_Controller-Request.xml 23 KB

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