Zend_Controller-Migration.xml 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.controller.migration">
  4. <title>Переход с предыдущих версий</title>
  5. <para>
  6. API компонент системы MVC претерпевал изменения со временем. Если вы
  7. начали использование Zend Framework с его ранних версий, то следуйте
  8. приведенным ниже рекомендациям по переносу вашего кода на новую
  9. архитектуру.
  10. </para>
  11. <sect2 id="zend.controller.migration.fromoneseventooneeight">
  12. <title>Переход с 1.7.x на 1.8.0 и более поздние версии</title>
  13. <sect3 id="zend.controller.migration.fromoneseventooneeight.router">
  14. <title>Изменения в стандартном маршруте</title>
  15. <para>
  16. Поскольку в новый стандартный маршрут были добавлены
  17. переводимые сегменты, символ <code>@</code> стал
  18. специальным символом в начале сегмента маршрута.
  19. Для того, чтобы можно было использовать его в статических
  20. сегментах, вы должны экранировать его путем добавления второго
  21. символа <code>@</code>. То же самое правило теперь применяется
  22. и к символу <code>:</code>.
  23. </para>
  24. </sect3>
  25. </sect2>
  26. <sect2 id="zend.controller.migration.fromonesixtooneseven">
  27. <title>Переход с 1.6.x на 1.7.0 и более поздние версии</title>
  28. <sect3 id="zend.controller.migration.fromonesixtooneseven.dispatcher">
  29. <title>Изменения в интерфейсе диспетчера</title>
  30. <para>
  31. Пользователи обратили наше внимание на тот факт, что
  32. <classname>Zend_Controller_Action_Helper_ViewRenderer</classname>
  33. использует не присутствующий в интерфейсе метод из
  34. абстрактного класса диспетчера. Мы добавили
  35. этот метод в интерфейс диспетчера для того,
  36. чтобы гарантировать работу созданного вами диспетчера с
  37. классами, входящими в поставку Zend Framework:
  38. </para>
  39. <itemizedlist>
  40. <listitem><para>
  41. <code>formatModuleName()</code>: должен принимать
  42. необработанное имя контроллера (в том виде, в котором оно
  43. хранится в объекте запроса) и преобразовывать его в имя
  44. класса контроллера, наследующего от
  45. <classname>Zend_Controller_Action</classname>.
  46. </para></listitem>
  47. </itemizedlist>
  48. </sect3>
  49. </sect2>
  50. <sect2 id="zend.controller.migration.fromoneohtoonesix">
  51. <title>Переход с 1.5.x на 1.6.0 и более поздние версии</title>
  52. <sect3 id="zend.controller.migration.fromoneohtoonesix.dispatcher">
  53. <title>Изменения в интерфейсе диспетчера</title>
  54. <para>
  55. Пользователи обратили наше внимание на тот факт, что
  56. <classname>Zend_Controller_Front</classname> и
  57. <classname>Zend_Controller_Router_Route_Module</classname> используют
  58. методы диспетчера, которые не определены в его интерфейсе.
  59. Мы добавили следующие три метода в его интерфейс для того,
  60. чтобы гарантировать работу созданного вами диспетчера с
  61. классами, входящими в поставку Zend Framework:
  62. </para>
  63. <itemizedlist>
  64. <listitem><para>
  65. <code>getDefaultModule()</code>: должен возвращать имя
  66. используемого по умолчанию модуля.
  67. </para></listitem>
  68. <listitem><para>
  69. <code>getDefaultControllerName()</code>: должен возвращать
  70. имя используемого по умолчанию контроллера.
  71. </para></listitem>
  72. <listitem><para>
  73. <code>getDefaultAction()</code>: должен возвращать имя
  74. используемого по умолчанию действия.
  75. </para></listitem>
  76. </itemizedlist>
  77. </sect3>
  78. </sect2>
  79. <sect2 id="zend.controller.migration.fromoneohtoonefive">
  80. <title>Переход с 1.0.x на 1.5.0 и более поздние версии</title>
  81. <para>
  82. Хотя основной набор функциональных возможностей остался тем же, и
  83. все документированные возможности не претерпели изменений, есть одна
  84. <emphasis>недокументированная</emphasis> "возможность", которая была
  85. изменена.
  86. </para>
  87. <para>
  88. При написании URL-ов, документированным способом написания имен
  89. действий в формате camelCase является использование разделителей
  90. слов. По умолчанию это '.' или '-', но они могут быть заменены на
  91. другие символы путем настройки диспетчера. Диспетчер внутри себя
  92. приводит имена действий к нижнему регистру и использует эти
  93. разделители слов для "пересборки" имен действий с использованием
  94. формата camelCase. Но из-за того, что функции PHP не чувствительны к
  95. регистру, вы <emphasis>могли</emphasis> по-прежнему писать URL-ы в
  96. формате camelCasе, и результатом был запуск тех же методов
  97. действий. Например, 'camel-cased' должен был преобразовываться
  98. диспетчером в 'camelCasedAction', а 'camelCased' - в
  99. 'camelcasedAction', но из-за нечувствительности PHP к регистру имен
  100. функций в обоих случаях будет произведен вызов одного и того же
  101. метода.
  102. </para>
  103. <para>
  104. Это вызывало проблемы с ViewRenderer при определении имени скрипта
  105. вида. Документированный способ состоит в том, что все разделители
  106. слов преобразуются в тире, и слова приводятся к нижнему регистру.
  107. Это создает семантическую связь между действиями и скриптами видов,
  108. а нормализация гарантирует, что скрипты могут быть найдены. Тем не
  109. менее, если вызывается действие с именем 'camelCased' и благополучно
  110. обработано, то разделитель слов более не присутствует в имени, и
  111. ViewRenderer пытается вызвать другой скрипт вида -
  112. 'camelcased.phtml' вместо 'camel-cased.phtml'.
  113. </para>
  114. <para>
  115. Некоторые разработчики полагались на эту незапланированную
  116. "возможность". Тем не менее, некоторые изменения в дереве 1.5.0,
  117. привели к тому, что ViewRenderer более не ищет такие пути;
  118. семантическая связь теперь усилена. Главное, диспетчер
  119. теперь чувствителен к регистру в именах действий. Это значит, что
  120. ссылка на действие через URL с использованием формата camelCase
  121. не будет приводить к вызову того же метода, что и с использованием
  122. разделителей слов (т.е. 'camel-casing').
  123. </para>
  124. <para>
  125. Если получилось, что вы используете эту "возможность", то в имеете
  126. несколько вариантов решения:
  127. </para>
  128. <itemizedlist>
  129. <listitem><para>
  130. Наилучший вариант: переименуйте ваши скрипты вида. Плюсы:
  131. будущая совместимость. Минусы: если вы имеете много скриптов
  132. вида, которые полагаются на старое, незапланированное
  133. поведение, то вам придется сделать много переименований.
  134. </para></listitem>
  135. <listitem>
  136. <para>
  137. Второй лучший вариант: ViewRenderer теперь делегирует
  138. определение скриптов вида инфлектору
  139. <classname>Zend_Filter_Inflector</classname>; вы можете изменить
  140. правила инфлектора так, чтобы он более не разделял слова в
  141. имени действия знаком тире:
  142. </para>
  143. <programlisting language="php"><![CDATA[
  144. $viewRenderer =
  145. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  146. $inflector = $viewRenderer->getInflector();
  147. $inflector->setFilterRule(':action', array(
  148. new Zend_Filter_PregReplace(
  149. '#[^a-z0-9' . preg_quote(DIRECTORY_SEPARATOR, '#') . ']+#i',
  150. ''
  151. ),
  152. 'StringToLower'
  153. ));
  154. ]]></programlisting>
  155. <para>
  156. Приведенный выше код изменит инфлектор таким образом, чтобы
  157. он более не разделял слова в имени действия знаком тире; вы
  158. можете также убрать фильтр 'StringToLower', если хотите,
  159. чтобы реальные имена скриптов вида тоже были в формате
  160. camelCase.
  161. </para>
  162. <para>
  163. Если переименование скриптов вида слишком утомительно или
  164. требует много времени, то этот вариант будет наилучшим
  165. решением на тот период, пока вы не найдете время на
  166. переименование.
  167. </para>
  168. </listitem>
  169. <listitem>
  170. <para>
  171. Менее желательное решение: Вы можете заставить диспетчер
  172. принимать имена действий в формате camelCase, установив
  173. новый флаг фронт-контроллера 'useCaseSensitiveActions':
  174. </para>
  175. <programlisting language="php"><![CDATA[
  176. $front->setParam('useCaseSensitiveActions', true);
  177. ]]></programlisting>
  178. <para>
  179. Это позволит вам использовать camelCase в URL-ах и они будут
  180. приводить к запуску тех действий, что и при использовании
  181. разделителей слов. Тем не менее, это будет означать, что
  182. исходная проблема может повлечь за собой другие; возможно,
  183. вам потребуется также использовать описанный выше второй
  184. вариант, чтобы все работало наверняка.
  185. </para>
  186. <para>
  187. Также заметьте, что использование этого флага приведет к
  188. появлению предупреждения (notice) о том, что его
  189. использование не рекомендуется.
  190. </para>
  191. </listitem>
  192. </itemizedlist>
  193. </sect2>
  194. <sect2 id="zend.controller.migration.fromzeroninethree">
  195. <title>Переход с 0.9.3 на 1.0.0RC1 и более поздние версии</title>
  196. <para>
  197. Основные изменения, появившиеся в 1.0.0RC1 - это добавление
  198. включенного по умолчанию плагина
  199. <link linkend="zend.controller.plugins.standard.errorhandler">ErrorHandler</link>
  200. и помощника действий <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
  201. Пожалуйста, прочитайте внимательно документацию к ним, чтобы понять,
  202. как они работают, и как они могут повлиять на работу ваших
  203. приложений.
  204. </para>
  205. <para>
  206. Плагин <code>ErrorHandler</code> производит в методе
  207. <code>postDispatch()</code> проверку на предмет исключений и
  208. переход (forwarding) к определенному контроллеру-обработчику
  209. исключений. Вы можете отключить его путем установки параметра
  210. <code>noErrorHandler</code> во фронт-контроллере:
  211. </para>
  212. <programlisting language="php"><![CDATA[
  213. $front->setParam('noErrorHandler', true);
  214. ]]></programlisting>
  215. <para>
  216. Помощник действий <code>ViewRenderer</code> автоматизирует
  217. добавление вида в контроллеры действий и производит авторендеринг
  218. скрипта вида, выбранного по текущему действию. Первая проблема, с
  219. которой вы можете встретиться - у вас есть действия,
  220. которые не производят рендеринг скриптов вида и не производят
  221. переход или перенаправление, поскольку <code>ViewRenderer</code>
  222. будет пытаться запустить скрипт вида, выбранного по имени действия.
  223. </para>
  224. <para>
  225. Есть несколько стратегий, используя которые, вы можете обновить свой
  226. код. В краткострочной перспективе решением может быть глобальное
  227. отключение <code>ViewRenderer</code> во фронт-контроллере до
  228. начала процесса диспетчеризации:
  229. </para>
  230. <programlisting language="php"><![CDATA[
  231. // $front является экземпляром Zend_Controller_Front
  232. $front->setParam('noViewRenderer', true);
  233. ]]></programlisting>
  234. <para>
  235. Но в долгосрочной перспективе это не лучшее решение, поскольку
  236. оно означает, что вам в будущем придется писать больше кода.
  237. </para>
  238. <para>
  239. Когда вы будете готовы начать использование функционала
  240. <code>ViewRenderer</code>, то необходимо проверить некоторые места в
  241. коде контроллеров. Первое, просмотрите методы действий (методы,
  242. заканчивающиеся на 'Action') и определите, что делает каждый метод.
  243. Если не происходит ничего из следующего, то нужно произвести
  244. изменения:
  245. </para>
  246. <itemizedlist>
  247. <listitem><para>
  248. Вызов <varname>$this-&gt;render()</varname>
  249. </para></listitem>
  250. <listitem><para>
  251. Вызов <varname>$this-&gt;_forward()</varname>
  252. </para></listitem>
  253. <listitem><para>
  254. Вызов <varname>$this-&gt;_redirect()</varname>
  255. </para></listitem>
  256. <listitem><para>
  257. Вызов помощника действий <code>Redirector</code>
  258. </para></listitem>
  259. </itemizedlist>
  260. <para>
  261. Наиболее легким способом будет отключение авторендеринга в данном
  262. методе:
  263. </para>
  264. <programlisting language="php"><![CDATA[
  265. $this->_helper->viewRenderer->setNoRender();
  266. ]]></programlisting>
  267. <para>
  268. Если вы обнаружили, что ни один из методов действий не производит
  269. рендеринг, переход или перенаправление, то, скорее всего, нужно
  270. поместить эту строку в методы
  271. <code>preDispatch()</code> или <code>init()</code>:
  272. </para>
  273. <programlisting language="php"><![CDATA[
  274. public function preDispatch()
  275. {
  276. // отключение авторендеринга скриптов вида
  277. $this->_helper->viewRenderer->setNoRender()
  278. // ... еще код ..
  279. }
  280. ]]></programlisting>
  281. <para>
  282. Если вы вызываете <code>render()</code> и используете
  283. <link linkend="zend.controller.modular">определенную соглашением
  284. модульную структуру директорий</link>, то нужно
  285. изменить свой код так, чтобы использовался авторендеринг:
  286. </para>
  287. <itemizedlist>
  288. <listitem>
  289. <para>
  290. Если производится рендеринг нескольких скриптов вида в
  291. одном действии, то не нужно ничего изменять.
  292. </para>
  293. </listitem>
  294. <listitem>
  295. <para>
  296. Если производится простой вызов метода
  297. <code>render()</code> без аргументов, то можете удалить
  298. соответствующие строки.
  299. </para>
  300. </listitem>
  301. <listitem>
  302. <para>
  303. Если вызывается <code>render()</code> с аргументами и не
  304. производится впоследствии каких-либо действий или рендеринга
  305. нескольких скриптов вида, то можно заменить эти вызовы на
  306. чтение <varname>$this-&gt;_helper-&gt;viewRenderer()</varname>.
  307. </para>
  308. </listitem>
  309. </itemizedlist>
  310. <para>
  311. На тот случай, если вы не используете определенную соглашением
  312. модульную структуру директорий, есть набор методов для
  313. установки базового пути к видам и спецификаций пути ко скрипту,
  314. поэтому вы сможете и в этом случае использовать
  315. <code>ViewRenderer</code>. Информацию об этих методах вы найдете в
  316. <link linkend="zend.controller.actionhelpers.viewrenderer">документации
  317. по ViewRenderer</link>
  318. </para>
  319. <para>
  320. Если вы используете объект вида из реестра, создали свой объект
  321. вида, либо используете другие реализации встроенного, то может
  322. потребоваться добавить этот объект в <code>ViewRenderer</code>. Это
  323. легко можно сделать в любой момент времени.
  324. </para>
  325. <itemizedlist>
  326. <listitem>
  327. <para>
  328. До начала диспетчеризации экземпляра фронт-контроллера:
  329. </para>
  330. <programlisting language="php"><![CDATA[
  331. // Предполагается, что $view уже определен
  332. $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
  333. Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
  334. ]]></programlisting>
  335. </listitem>
  336. <listitem>
  337. <para>
  338. В любой точке процесса загрузки (bootstrap process):
  339. </para>
  340. <programlisting language="php"><![CDATA[
  341. $viewRenderer =
  342. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  343. $viewRenderer->setView($view);
  344. ]]></programlisting>
  345. </listitem>
  346. </itemizedlist>
  347. <para>
  348. Есть много способов модификации <code>ViewRenderer</code>, включая
  349. установку других скриптов вида для рендеринга, определение замещений
  350. для всех замещаемых элементов пути ко скрипту вида (включая
  351. суффикс), выбор именованного сегмента ответа в качестве
  352. используемого и др. Если вы не используете определенную соглашением
  353. модульную структуру директорий, то можете ассоциировать с
  354. <code>ViewRenderer</code> другие спецификации путей.
  355. </para>
  356. <para>
  357. Рекомендуется адаптировать свой код для использования
  358. <code>ErrorHandler</code> и <code>ViewRenderer</code>, так как
  359. сейчас это лежащий в основе фреймворка функционал.
  360. </para>
  361. </sect2>
  362. <sect2 id="zend.controller.migration.fromzeroninetwo">
  363. <title>Переход с 0.9.2 на 0.9.3 и более поздние версии</title>
  364. <para>
  365. В версии 0.9.3 были добавлены <link
  366. linkend="zend.controller.actionhelpers">помощники действий</link>
  367. (action helpers).
  368. Это изменение включает в себя удаление перечисленных ниже методов
  369. из-за того, что сейчас они инкапсулированы в
  370. <link linkend="zend.controller.actionhelpers.redirector">помощнике
  371. перенаправлений</link> (redirector action helper):
  372. </para>
  373. <itemizedlist>
  374. <listitem>
  375. <para>
  376. <code>setRedirectCode()</code>; используйте
  377. <code>Zend_Controller_Action_Helper_Redirector::setCode()</code>.
  378. </para>
  379. </listitem>
  380. <listitem>
  381. <para>
  382. <code>setRedirectPrependBase()</code>; используйте
  383. <code>Zend_Controller_Action_Helper_Redirector::setPrependBase()</code>.
  384. </para>
  385. </listitem>
  386. <listitem>
  387. <para>
  388. <code>setRedirectExit()</code>; используйте
  389. <code>Zend_Controller_Action_Helper_Redirector::setExit()</code>.
  390. </para>
  391. </listitem>
  392. </itemizedlist>
  393. <para>
  394. Более подробную информацию о том, как извлекать и работать с
  395. объектами действий, читайте в <link
  396. linkend="zend.controller.actionhelpers">документации по помощникам
  397. действий</link>. Об установке опций перенаправления и альтернативных
  398. методах перенаправления читайте в <link
  399. linkend="zend.controller.actionhelpers.redirector">документации по
  400. помощнику перенаправлений</link>.
  401. </para>
  402. </sect2>
  403. <sect2 id="zend.controller.migration.fromzerosix">
  404. <title>Переход с 0.6.0 на 0.8.0 и более поздние версии</title>
  405. <para>
  406. Базовое использование компонент MVC не изменилось:
  407. </para>
  408. <programlisting language="php"><![CDATA[
  409. Zend_Controller_Front::run('/path/to/controllers');
  410. ]]></programlisting>
  411. <para>
  412. Тем не менее, структура директорий была подвергнута пересмотру,
  413. некоторые компоненты были удалены, другие добавлены или
  414. переименованы. Изменения включают в себя следующее:
  415. </para>
  416. <itemizedlist>
  417. <listitem>
  418. <para>
  419. <classname>Zend_Controller_Router</classname> удален в пользу
  420. использования Rewrite Router.
  421. </para>
  422. </listitem>
  423. <listitem>
  424. <para>
  425. <classname>Zend_Controller_RewriteRouter</classname> переименован в
  426. <classname>Zend_Controller_Router_Rewrite</classname>, теперь это
  427. стандартный маршрутизатор, поставляемый с фреймворком.
  428. <classname>Zend_Controller_Front</classname> будет использовать его по
  429. умолчанию, если не был установлен другой маршрутизатор.
  430. </para>
  431. </listitem>
  432. <listitem>
  433. <para>
  434. Добавлен новый класс маршрута для использования с Rewrite
  435. Router - <classname>Zend_Controller_Router_Route_Module</classname>.
  436. Он включает в себя маршрут по умолчанию, используемый
  437. MVC, и поддерживает <link
  438. linkend="zend.controller.modular">модули
  439. контроллеров</link>.
  440. </para>
  441. </listitem>
  442. <listitem>
  443. <para>
  444. <classname>Zend_Controller_Router_StaticRoute</classname> переименован
  445. в <classname>Zend_Controller_Router_Route_Static</classname>.
  446. </para>
  447. </listitem>
  448. <listitem>
  449. <para>
  450. <classname>Zend_Controller_Dispatcher</classname> переименован в
  451. <classname>Zend_Controller_Dispatcher_Standard</classname>.
  452. </para>
  453. </listitem>
  454. <listitem>
  455. <para>
  456. Аргументы метода
  457. <code>Zend_Controller_Action::_forward()</code> изменились.
  458. Его сигнатура теперь:
  459. </para>
  460. <programlisting language="php"><![CDATA[
  461. final protected function _forward($action,
  462. $controller = null,
  463. $module = null,
  464. array $params = null);
  465. ]]></programlisting>
  466. <para>
  467. <varname>$action</varname> - обязательный аргумент. Если не был
  468. определен контроллер, то предполагается, что вызывается
  469. действие в текущем контроллере. <varname>$module</varname> всегда
  470. игнорируется, если не определен контроллер. Все переданные в
  471. аргументе <varname>$params</varname> параметры будут добавлены в
  472. объект запроса. Если вы не запрашиваете контроллер или
  473. модуль, но нужно передать параметры, то просто укажите null
  474. на месте соответствующих аргументов.
  475. </para>
  476. </listitem>
  477. </itemizedlist>
  478. </sect2>
  479. <sect2 id="zend.controller.migration.fromzerotwo">
  480. <title>Переход с 0.2.0 и более ранних версий на 0.6.0</title>
  481. <para>
  482. Базовое использование компонент системы MVC не изменилось,
  483. следующий код будет корректно выполняться и в версии 0.6.0:
  484. </para>
  485. <programlisting language="php"><![CDATA[
  486. Zend_Controller_Front::run('/path/to/controllers');
  487. ]]></programlisting>
  488. <programlisting language="php"><![CDATA[
  489. /* -- создание маршрутизатора -- */
  490. $router = new Zend_Controller_RewriteRouter();
  491. $router->addRoute('user',
  492. 'user/:username',
  493. array('controller' => 'user', 'action' => 'info')
  494. );
  495. /* -- установка его во фронт-контроллере -- */
  496. $ctrl = Zend_Controller_Front::getInstance();
  497. $ctrl->setRouter($router);
  498. /* -- установка директории контроллеров и запуск диспетчеризации -- */
  499. $ctrl->setControllerDirectory('/path/to/controllers');
  500. $ctrl->dispatch();
  501. ]]></programlisting>
  502. <para>
  503. Рекомендуется использовать объект ответа для сбора содержимого и
  504. заголовков. Это дает большую гибкость при переключении
  505. между разными форматами вывода (например, JSON или XML вместо XHTML)
  506. в приложениях. По умолчанию <code>dispatch()</code> будет возвращать
  507. ответ, отправляя заголовки и выводя весь контент. Можно также
  508. сделать так, чтобы фронт-контроллер возвращал ответ, используя метод
  509. <code>returnResponse()</code>, и затем выводить ответ так, как нужно
  510. вам. Будущая версия фронт-контроллер может принуждать к
  511. использованию объекта ответа посредством буферизации вывода.
  512. </para>
  513. <para>
  514. Также добавлено много новых функциональных возможностей,
  515. расширяющих существующий API, они описаны в документации.
  516. </para>
  517. <para>
  518. Основные изменения, о которых следует знать, касаются расширения
  519. существующих компонент. Наиболее важные из них следующие:
  520. </para>
  521. <itemizedlist>
  522. <listitem>
  523. <para>
  524. <code>Zend_Controller_Front::dispatch()</code> по умолчанию
  525. отлавливает все исключения в объекте ответа и не отображает
  526. их для предотвращения раскрытия данных о системе. Вы
  527. можете переопределить это поведение несколькими способами:
  528. </para>
  529. <itemizedlist>
  530. <listitem>
  531. <para>
  532. Установка <code>throwExceptions()</code> во
  533. фронт-контроллере:
  534. </para>
  535. <programlisting language="php"><![CDATA[
  536. $front->throwExceptions(true);
  537. ]]></programlisting>
  538. </listitem>
  539. <listitem>
  540. <para>
  541. Установка <code>renderExceptions()</code> в объекте
  542. ответа:
  543. </para>
  544. <programlisting language="php"><![CDATA[
  545. $response->renderExceptions(true);
  546. $front->setResponse($response);
  547. $front->dispatch();
  548. // или:
  549. $front->returnResponse(true);
  550. $response = $front->dispatch();
  551. $response->renderExceptions(true);
  552. echo $response;
  553. ]]></programlisting>
  554. </listitem>
  555. </itemizedlist>
  556. </listitem>
  557. <listitem><para>
  558. <code>Zend_Controller_Dispatcher_Interface::dispatch()</code>
  559. теперь принимает и возвращает объект запроса
  560. <xref linkend="zend.controller.request" />
  561. вместо метки <classname>Zend_Controller_Dispatcher_Token</classname>.
  562. </para></listitem>
  563. <listitem><para>
  564. <code>Zend_Controller_Router_Interface::route()</code>
  565. теперь принимает и возвращает объект ответа
  566. <xref linkend="zend.controller.request" />
  567. вместо метки <classname>Zend_Controller_Dispatcher_Token</classname>
  568. </para></listitem>
  569. <listitem>
  570. <para>
  571. Изменения <classname>Zend_Controller_Action</classname> включают в
  572. себя следующее:
  573. </para>
  574. <itemizedlist>
  575. <listitem><para>
  576. Его конструктор теперь включает в себя три аргумента:
  577. <code>Zend_Controller_Request_Abstract $request</code>,
  578. <code>Zend_Controller_Response_Abstract $response</code>
  579. и <code>array $params</code> (необязательный).
  580. <code>Zend_Controller_Action::__construct()</code>
  581. использует их для установки запроса, ответа и свойств
  582. объекта (аргументов вызова); переопределяя конструктор,
  583. вам следует реализовать те же операции.
  584. Но лучше использовать метод <code>init()</code> для
  585. выполнения любого конфигурирования экземпляра класса,
  586. так как этот метод вызывается в конце конструктора.
  587. </para></listitem>
  588. <listitem><para>
  589. Метод <code>run()</code> теперь не определен с ключевым
  590. словом <code>final</code>, но он также и не используется
  591. во фронт-контроллере; единственным его назначением
  592. является использование класса как контроллера страниц.
  593. Теперь он принимает два необязательных аргумента –
  594. <code>Zend_Controller_Request_Abstract $request</code>
  595. и <code>Zend_Controller_Response_Abstract $response</code>.
  596. </para></listitem>
  597. <listitem><para>
  598. <code>indexAction()</code> уже не обязателен для
  599. определения, но все же рекомендуется определять его в
  600. качестве действия по умолчанию. Это позволяет
  601. использовать RewriteRouter и контроллеры действий для
  602. указания других используемых по умолчанию методов
  603. действий.
  604. </para></listitem>
  605. <listitem><para>
  606. <code>__call()</code> должен переопределяться для
  607. автоматической обработки вызовов действий, не
  608. определенных в классе контроллера.
  609. </para></listitem>
  610. <listitem><para>
  611. Метод <code>_redirect()</code> теперь принимает второй
  612. необязательный аргумент, HTTP-код, который должен
  613. возвращаться при перенаправлении, и третий
  614. необязательный аргумент, <varname>$prependBase</varname>,
  615. который указывает, что базовый URL, зарегистрированный в
  616. объекте запроса, должен предшествовать URL, переданному
  617. в первом аргументе.
  618. </para></listitem>
  619. <listitem>
  620. <para>
  621. Свойство <code>_action</code> больще не
  622. устанавливается. Это свойство было объектом класса
  623. <classname>Zend_Controller_Dispatcher_Token</classname>,
  624. которй больше не существует в текущем воплощении.
  625. Единственным назначением метки (token) было
  626. предоставление информации о запрошенных контроллере,
  627. действии и параметрах URL. Эта информация теперь
  628. доступна в объекте запроса, и доступ к ней можно
  629. получить следующим образом:
  630. </para>
  631. <programlisting language="php"><![CDATA[
  632. // Извлечение имени запрошенного контроллера
  633. // Ранее доступ был через $this->_action->getControllerName().
  634. // Пример ниже использует getRequest(), хотя вы можете обращаться напрямую
  635. // ко свойству $_request; рекомендуется использовать getRequest(), поскольку
  636. // родительский класс может переопределить доступ к объекту запроса.
  637. $controller = $this->getRequest()->getControllerName();
  638. // Извлечение имени запрошенного действия
  639. // Ранее доступ был через $this->_action->getActionName().
  640. $action = $this->getRequest()->getActionName();
  641. // Извлечение параметров запроса
  642. // Оно не изменилось; _getParams() и _getParam() просто вызывают аналогичные
  643. // методы объекта запроса
  644. $params = $this->_getParams();
  645. // запрашивается параметр 'foo', если параметр не найден,
  646. // то используется значение по умолчанию 'default'
  647. $foo = $this->_getParam('foo', 'default');
  648. ]]></programlisting>
  649. </listitem>
  650. <listitem>
  651. <para>
  652. Удален метод <code>noRouteAction()</code>.
  653. Подходящим способом обработки несуществующих методов
  654. действий будет перенаправление к действию по
  655. умолчанию через <code>__call()</code>:
  656. </para>
  657. <programlisting language="php"><![CDATA[
  658. public function __call($method, $args)
  659. {
  660. // Если запрошен несуществующий метод действия, то вызывается метод
  661. // действия по умолчанию:
  662. if ('Action' == substr($method, -6)) {
  663. return $this->defaultAction();
  664. }
  665. throw new Zend_Controller_Exception('Invalid method called');
  666. }
  667. ]]></programlisting>
  668. </listitem>
  669. </itemizedlist>
  670. </listitem>
  671. <listitem><para>
  672. Удален метод
  673. <code>Zend_Controller_RewriteRouter::setRewriteBase()</code>.
  674. Вместо него используйте
  675. <code>Zend_Controller_Front::setBaseUrl()</code> (или
  676. <code>Zend_Controller_Request_Http::setBaseUrl()</code>,
  677. если используется класс запроса).
  678. </para></listitem>
  679. <listitem><para>
  680. <classname>Zend_Controller_Plugin_Interface</classname> был заменен на
  681. <classname>Zend_Controller_Plugin_Abstract</classname>. Все методы теперь
  682. принимают и возвращают объект ответа
  683. <xref linkend="zend.controller.request" /> вместо метки
  684. диспетчеризации.
  685. </para></listitem>
  686. </itemizedlist>
  687. </sect2>
  688. </sect1>
  689. <!--
  690. vim:se ts=4 sw=4 et:
  691. -->