[MANUAL] English:
[zend.git] / documentation / manual / ru / module_specs / Zend_Controller-FrontController.xml
blob2d6b3e77fc5668d3f117663f48e99b3a16cd8f26
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.controller.front">
4     <title>Фронт-контроллер</title>
6     <sect2 id="zend.controller.front.overview">
7         <title>Обзор</title>
9         <para>
10             <classname>Zend_Controller_Front</classname> реализует
11             <ulink url="http://www.martinfowler.com/eaaCatalog/frontController.html">паттерн
12             Front Controller</ulink>, используемый в приложениях <ulink
13                 url="http://en.wikipedia.org/wiki/Model-view-controller">MVC</ulink>.
14             Его назначение состоит в инициализации окружения запроса, проложении
15             маршрута приходящего запроса и последующем запуске выявленных
16             действий. Он агрегирует все ответы и возвращает их по завершении
17             процесса.
18         </para>
20         <para>
21             <classname>Zend_Controller_Front</classname> также реализует
22             <ulink url="http://en.wikipedia.org/wiki/Singleton_pattern">паттерн
23             Singleton</ulink>, это означает, что в любое время может быть
24             доступен только один экземпляр этого класса. Это позволяет ему также
25             выступать в качестве реестра, в котором хранятся другие объекты,
26             участвующие в процессе диспетчеризации.
27         </para>
29         <para>
30             <classname>Zend_Controller_Front</classname> регистрирует в себе <link
31             linkend="zend.controller.plugins">брокер плагинов</link> (plugin
32             broker), что позволяет с помощью плагинов отслеживать события,
33             инициируемые фронт-контроллером.
34             В большинстве случаев это дает возможность подгонять
35             процесс диспетчеризации под конкретный сайт без расширения
36             фронт-контроллера для добавления функциональности.
37         </para>
39         <para>
40             Фронт-контроллеру для его работы необходим, как минимум,
41             один или более путей к директориям, содержащим
42             <link linkend="zend.controller.action">контроллеры действий</link>.
43             Можно также использовать различные методы для дальнейшей
44             настройки конфигураций фронт-контроллера и его помощников.
45         </para>
47         <note>
48             <title>Поведение по умолчанию</title>
49             <para>
50                 По умолчанию фронт-контроллер загружает плагин <link
51                 linkend="zend.controller.plugins.standard.errorhandler">ErrorHandler</link>
52                 и помощник действий <link
53                 linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
54                 Это сделано для упрощения обработки ошибок и рендеринга видов в
55                 контроллерах, соответственно.
56             </para>
58             <para>
59                 Для того, чтобы отключить <code>ErrorHandler</code>, произведите
60                 следующее до вызова метода <code>dispatch()</code>:
61             </para>
63             <programlisting language="php"><![CDATA[
64 // Отключение плагина ErrorHandler:
65 $front->setParam('noErrorHandler', true);
66 ]]></programlisting>
68             <para>
69                 Для того, чтобы отключить <code>ViewRenderer</code>, сделайте
70                 следующее до вызова метода <code>dispatch()</code>:
71             </para>
73             <programlisting language="php"><![CDATA[
74 // Отключение помощника ViewRenderer:
75 $front->setParam('noViewRenderer', true);
76 ]]></programlisting>
77         </note>
79     </sect2>
81     <sect2 id="zend.controller.front.methods.primary">
82         <title>Ключевые методы</title>
84         <para>
85             Фронт-контроллер имеет несколько аксессоров для настройки его
86             конфигурации. Тем не менее, он имеет несколько ключевых в
87             его функционале методов.
88         </para>
90         <sect3 id="zend.controller.front.methods.primary.getinstance">
91             <title>getInstance()</title>
93             <para>
94                 <code>getInstance()</code> используется для получения экземпляра
95                 фронт-контроллера. Поскольку фронт-контроллер реализует паттерн
96                 Singleton, то это также единственно доступный способ
97                 инстанцирования объекта фронт-контроллера.
98             </para>
100             <programlisting language="php"><![CDATA[
101 $front = Zend_Controller_Front::getInstance();
102 ]]></programlisting>
103         </sect3>
105         <sect3 id="zend.controller.front.methods.primary.setcontrollerdirectory">
106             <title>setControllerDirectory() и addControllerDirectory()</title>
108             <para>
109                 <code>setControllerDirectory()</code> используется для того,
110                 чтобы указать <link
111                 linkend="zend.controller.dispatcher">диспетчеру</link>, где
112                 искать файлы классов <link
113                 linkend="zend.controller.action">контроллеров действий</link>.
114                 Он принимает один путь или ассоциативный массив пар
115                 модуль => путь в качестве параметра.
116             </para>
118             <para>
119                 Примеры:
120             </para>
122             <programlisting language="php"><![CDATA[
123 // Установка директории контроллеров, используемой по умолчанию:
124 $front->setControllerDirectory('../application/controllers');
126 // Одновременная установка нескольких директорий модулей:
127 $front->setControllerDirectory(array(
128     'default' => '../application/controllers',
129     'blog'    => '../modules/blog/controllers',
130     'news'    => '../modules/news/controllers',
133 // Добавление директории модуля 'foo':
134 $front->addControllerDirectory('../modules/foo/controllers', 'foo');
135 ]]></programlisting>
137             <note>
138                 <para>
139                     Если вы используете <code>addControllerDirectory()</code>
140                     без имени модуля, то он установит директорию для модуля
141                     <code>default</code>. Если директория уже существует, то она
142                     будет перезаписана.
143                 </para>
144             </note>
146             <para>
147                 Можно получить текущие установки для директорий
148                 контроллеров, используя метод
149                 <code>getControllerDirectory()</code>. Он вернет массив пар
150                 модуль => директория.
151             </para>
152         </sect3>
154         <sect3 id="zend.controller.front.methods.primary.addmoduledirectory">
155             <title>addModuleDirectory() и getModuleDirectory()</title>
157             <para>
158                 Одной из возможностей фронт-контроллера является то, что вы
159                 можете <link
160                     linkend="zend.controller.modular">определять модульную
161                 структуру директорий</link> для создания отдельных компонент,
162                 которые называются "модулями".
163             </para>
165             <para>
166                 Каждый модуль должен находиться в собственной директории и
167                 отражать структуру директорий используемого по умолчанию
168                 модуля - т.е., он должен содержать, как минимум, поддиректорию
169                 "controllers"; с ней, как правило, присутствует поддиректория
170                 "views" и другие поддиректории приложения.
171             </para>
173             <para>
174                 Метод <code>addModuleDirectory()</code> позволяет передавать имя
175                 директории, содержащей один или более директорий модулей.
176                 Он их сканирует и добавляет в качестве директорий контроллеров
177                 во фронт-контроллер.
178             </para>
180             <para>
181                 Если вы хотите получить путь к определенному модулю или к
182                 текущему модулю, то можете использовать метод
183                 <code>getModuleDirectory()</code>, при передаче имени модуля он
184                 возвращает путь к нему, иначе возвращается путь к текущему
185                 модулю.
186             </para>
187         </sect3>
189         <sect3 id="zend.controller.front.methods.primary.dispatch">
190             <title>dispatch()</title>
192             <para>
193                 <code>dispatch(Zend_Controller_Request_Abstract $request = null,
194                     Zend_Controller_Response_Abstract $response = null)</code>
195                     является "рабочей лошадкой" фронт-контроллера. Он может
196                     опционально принимать
197                     <link linkend="zend.controller.request">объект
198                     запроса</link> и/или
199                     <link linkend="zend.controller.response">объект
200                     ответа</link>, что дает разработчикам возможность передавать
201                     свои объекты.
202             </para>
204             <para>
205                 Если методу <code>dispatch()</code> не были переданы объект
206                 запроса или ответа, то он будет проверять, были ли ранее
207                 зарегистрированы объекты, и использовать их, либо инстанцировать
208                 версии по умолчанию (в обоих случаях по умолчанию будут
209                 использоваться разновидность HTTP).
210             </para>
212             <para>
213                 Аналогичным образом <code>dispatch()</code> производит проверку
214                 на уже зарегистрированные объекты
215                 <link linkend="zend.controller.router">маршрутизатора</link> и
216                 <link linkend="zend.controller.dispatcher">диспетчера</link>, и
217                 если они не найдены, то инстанцирует версии по умолчанию.
218             </para>
220             <para>
221                 Процесс диспетчеризации имеет три отдельных события:
222             </para>
224             <itemizedlist>
225                 <listitem><para>
226                     Маршрутизация
227                 </para></listitem>
228                 <listitem><para>
229                     Диспетчеризация
230                 </para></listitem>
231                 <listitem><para>
232                     Ответ
233                 </para></listitem>
234             </itemizedlist>
236             <para>
237                 Маршрутизация производится только один раз, когда вызывается
238                 <code>dispatch()</code>, при этом используются значения в
239                 объекте запроса. Диспетчеризация производится циклически. Запрос
240                 может означать вызов нескольких действий, контроллер или плагин
241                 могут сбрасывать объект запроса для дополнительного вызова
242                 других действий. Когда все действия выполнены, фронт-контроллер
243                 возвращает ответ.
244             </para>
245         </sect3>
247         <sect3 id="zend.controller.front.methods.primary.run">
248             <title>run()</title>
250             <para>
251                 <code>Zend_Controller_Front::run($path)</code> - статический
252                 метод, принимающий только путь к директории контроллеров. Он
253                 извлекает экземпляр фронт-контроллера через
254                 <link linkend="zend.controller.front.methods.primary.getinstance">getInstance()</link>),
255                 регистрирует этот путь через
256                 <link linkend="zend.controller.front.methods.primary.setcontrollerdirectory">setControllerDirectory()</link>, и в конце вызывает метод <link linkend="zend.controller.front.methods.primary.dispatch">dispatch()</link>.
257             </para>
259             <para>
260                 В сущности, <code>run()</code> представляет собой удобный
261                 метод, который можно использовать при разработке сайта, не
262                 требующего специальной настройки фронт-контроллера.
263             </para>
265             <programlisting language="php"><![CDATA[
266 // Инстанцирование фронт-контроллера, установка директории контроллера и
267 // выполнение диспетчеризации в одном вызове:
268 Zend_Controller_Front::run('../application/controllers');
269 ]]></programlisting>
270         </sect3>
271     </sect2>
273     <sect2 id="zend.controller.front.methods.environment">
274         <title>Методы-аксессоры для конфигурирования</title>
276         <para>
277             Кроме методов, перечисленных выше, есть методы-аксессоры, которые
278             можно использовать для управления конфигурацией фронт-контроллера -
279             и одновременно конфигурацией классов, которым фронт-контроллер
280             делегирует выполнение.
281         </para>
283         <itemizedlist>
284             <listitem>
285                 <para>
286                     <code>resetInstance()</code> может использоваться для сброса
287                     всех текущих настроек. Он в основном предназначен для
288                     тестирования, но может также использоваться в тех случаях,
289                     когда нужно связать между собой несколько
290                     фронт-контроллеров.
291                 </para>
292             </listitem>
294             <listitem>
295                 <para>
296                     <code>(set|get)DefaultControllerName()</code> позволяют
297                     установить другое имя используемого
298                     по умолчанию контроллера (иначе используется 'index') и
299                     получить текущее значение. Они служат посредниками к
300                     <link linkend="zend.controller.dispatcher">диспетчеру</link>.
301                 </para>
302             </listitem>
304             <listitem>
305                 <para>
306                     <code>(set|get)DefaultAction()</code> позволяют
307                     установить другое имя используемого по умолчанию действия
308                     (иначе используется 'index') и получить текущее
309                     значение. Они служат посредниками к
310                     <link linkend="zend.controller.dispatcher">диспетчеру</link>.
311                 </para>
312             </listitem>
314             <listitem>
315                 <para>
316                     <code>(set|get)Request()</code> позволяют установить
317                     класс <link linkend="zend.controller.request">запроса</link>
318                     или его объект для использования в процессе диспетчеризации
319                     и получить текущий объект. При установке объекта
320                     запроса вы можете передать имя класса запроса, в этом случае
321                     метод загрузит файл класса и инстанцирует его.
322                 </para>
323             </listitem>
325             <listitem>
326                 <para>
327                     <code>(set|get)Router()</code> позволяют установить
328                     класс
329                     <link linkend="zend.controller.router">маршрутизатора</link>
330                     или его объект, используемые в течение процесса
331                     диспетчеризации, и получить текущий объект. Когда
332                     устанавливается объект маршрутизатора, вы можете передать
333                     имя класса маршрутизатора, в этом случае метод загрузит файл
334                     класса и инстанцирует его.
335                 </para>
337                 <para>
338                     При извлечении объекта маршрутизатора сначала производится
339                     проверка, представлен ли во фронт-контроллере такой объект и
340                     в случае его отсутствия инстанцирует используемый по
341                     умолчанию маршрутизатор (Rewrite Router).
342                 </para>
343             </listitem>
345             <listitem>
346                 <para>
347                     <code>(set|get)BaseUrl()</code> дают возможность установить
348                     <link linkend="zend.controller.request.http.baseurl">базовый
349                     URL</link>, который удаляется из начала при
350                     маршрутизации запросов, и получить его текущее значение.
351                     Это значение передается объекту запроса непосредственно до
352                     маршрутизации.
353                 </para>
354             </listitem>
356             <listitem>
357                 <para>
358                     <code>(set|get)Dispatcher()</code> дают возможность
359                     установки класса
360                     <link linkend="zend.controller.dispatcher">диспетчера</link>
361                     или его объекта для использования в течение диспетчеризации,
362                     и получения текущего объекта. При установке объекта
363                     диспетчера можно передать имя класса диспетчера, в этом
364                     случае метод загрузит файл класса и инстанцирует его.
365                 </para>
367                 <para>
368                     При извлечении объекта диспетчера, метод сначала производит
369                     проверку того, представлен ли во фронт-контроллере такой
370                     объект и в случае его отсутствия инстанцирует диспетчер,
371                     используемый по умолчанию.
372                 </para>
373             </listitem>
375             <listitem>
376                 <para>
377                     <code>(set|get)Response()</code> дают возможность установить
378                     класс <link linkend="zend.controller.response">ответа</link>
379                     или его объект для использования в процессе диспетчеризации,
380                     и извлечь текущий объект. При установке объекта
381                     ответа можно передать имя класса ответа, в этом случае метод
382                     загрузит файл класса и инстанцирует его.
383                 </para>
384             </listitem>
386             <listitem>
387                 <para>
388                     <code>registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null)</code>
389                     позволяет регистрировать <link
390                         linkend="zend.controller.plugins">объекты плагинов</link>.
391                     Путем установки опционального параметра
392                     <varname>$stackIndex</varname>, вы можете
393                     контролировать порядок, в котором выполняются плагины.
394                 </para>
395             </listitem>
397             <listitem>
398                 <para>
399                     <code>unregisterPlugin($plugin)</code> позволяет отменять
400                     регистрацию <link
401                         linkend="zend.controller.plugins">объектов плагинов</link>.
402                     <varname>$plugin</varname> может быть как объектом плагина, так и строкой, обозначающей класс плагина, регистрацию которого надо отменить.
403                 </para>
404             </listitem>
406             <listitem>
407                 <para>
408                     <code>throwExceptions($flag)</code> используется для
409                     включения/отключения возможности генерации исключений в
410                     течение процесса диспетчеризации. По умолчанию исключения
411                     отлавливаются и размещаются в
412                     <link linkend="zend.controller.response">объекте
413                     ответа</link>; включение <code>throwExceptions()</code>
414                     переопределит это поведение
415                 </para>
417                 <para>
418                     Более полробную информацию читайте в <xref linkend="zend.controller.exceptions"/>.
419                 </para>
420             </listitem>
422             <listitem>
423                 <para>
424                     <code>returnResponse($flag)</code> используется для того,
425                     чтобы указать фронт-контроллеру - возвращать ли ответ
426                     из <code>dispatch()</code> (<constant>TRUE</constant>), либо ответ
427                     должен быть отправлен автоматически (<constant>FALSE</constant>). По
428                     умолчанию ответ отправляется автоматически
429                     (через вызов
430                     <code>Zend_Controller_Response_Abstract::sendResponse()</code>);
431                     включение <code>returnResponse()</code> переопределит это
432                     поведение.
433                 </para>
435                 <para>
436                     Ситуации, в которых может потребоваться возврат ответа,
437                     включают в себя проверку на предмет исключений до отправки
438                     ответа клиенту, необходимость журналирования различных
439                     аспектов ответа (таких, как заголовки) и т.д.
440                 </para>
441             </listitem>
442         </itemizedlist>
443     </sect2>
445     <sect2 id="zend.controller.front.methods.params">
446         <title>Параметры фронт-контроллера</title>
448         <para>
449             Во введении мы указали на то, что фронт-контроллер также выступает
450             как реестр для различных компонент контроллера. Это реализуется
451             через группу методов для параметров. Эти методы позволяют
452             регистрировать произвольные данные - объекты и переменные - во
453             фронт-контроллере, чтобы их можно было извлечь в любой точке цепочки
454             диспетчеризации. Эти значения передаются маршрутизатору, диспетчеру,
455             и контроллерам действий. Эти методы включают в себя:
456         </para>
458         <itemizedlist>
459             <listitem>
460                 <para>
461                     <code>setParam($name, $value)</code> дает возможность
462                     установить единственный параметр с именем <varname>$name</varname>
463                     и значением <varname>$value</varname>.
464                 </para>
465             </listitem>
467             <listitem>
468                 <para>
469                     <code>setParams(array $params)</code> позволяет
470                     установить несколько параметров одновременно с помощью
471                     ассоциативного массива.
472                 </para>
473             </listitem>
475             <listitem>
476                 <para>
477                     <code>getParam($name)</code> дает возможность извлечь один
478                     параметр за один раз, используя его имя <varname>$name</varname> в
479                     качестве идентификатора.
480                 </para>
481             </listitem>
483             <listitem>
484                 <para>
485                     <code>getParams()</code> позволяет извлечь все
486                     параметры за один раз.
487                 </para>
488             </listitem>
490             <listitem>
491                 <para>
492                     <code>clearParams()</code> позволяет удалить один параметр
493                     (путем передачи строкового идентификатора), нескольких
494                     параметров (путем передачи массива строковых
495                     идентификаторов) или весь стек параметров (без передачи
496                     чего-либо).
497                 </para>
498             </listitem>
499         </itemizedlist>
501         <para>
502             Есть несколько предопределенных параметров специально для
503             использования в цепочке диспетчеризации:
504         </para>
506         <itemizedlist>
507             <listitem>
508                 <para>
509                     <code>useDefaultControllerAlways</code> используется для
510                     указания
511                     <link linkend="zend.controller.dispatcher">диспетчеру</link>,
512                     что следует использовать контроллер по умолчанию в модуле
513                     по умолчанию для любых запросов, диспетчеризация которых
514                     невозможна (т.е. модуль, контроллер и/или действие не
515                     существуют). По умолчанию он отключен.
516                 </para>
518                 <para>
519                     См. <xref linkend="zend.controller.exceptions.internal"/> за
520                     более подробной информацией об использовании этого параметра
521                     настройки.
522                 </para>
523             </listitem>
525             <listitem>
526                 <para>
527                     <code>disableOutputBuffering</code> используется для
528                     указания
529                     <link linkend="zend.controller.dispatcher">диспетчеру</link>,
530                     что не следует использовать буферизацию вывода для сбора
531                     данных на вывод, генерируемых контроллерами действий. По
532                     умолчанию диспетчер собирает весь вывод и присоединяет его к
533                     телу содержимого в объекте ответа.
534                 </para>
535             </listitem>
537             <listitem>
538                 <para>
539                     <code>noViewRenderer</code> используется для отключения
540                     помощника <link
541                         linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
542                     Установите этот параметр в true для его отключения.
543                 </para>
544             </listitem>
546             <listitem>
547                 <para>
548                     <code>noErrorHandler</code> используется для отключения
549                     <link
550                         linkend="zend.controller.plugins.standard.errorhandler">плагина
551                         Error Handler</link>
552                     Установите этот параметр в true для его отключения.
553                 </para>
554             </listitem>
555         </itemizedlist>
556     </sect2>
558     <sect2 id="zend.controller.front.subclassing">
559         <title>Расширение фронт-контроллера</title>
561         <para>
562             При наследовании от фронт-контроллера, необходимо, как
563             минимум, переопределить метод <code>getInstance()</code>.
564         </para>
566         <programlisting language="php"><![CDATA[
567 class My_Controller_Front extends Zend_Controller_Front
569     public static function getInstance()
570     {
571         if (null === self::$_instance) {
572             self::$_instance = new self();
573         }
575         return self::$_instance;
576     }
578 ]]></programlisting>
580         <para>
581             Такое переопределение метода <code>getInstance()</code> гарантирует
582             то, что последующий вызов
583             <code>Zend_Controller_Front::getInstance()</code> вернет экземпляр
584             созданного вами подкласса вместо экземпляра
585             <classname>Zend_Controller_Front</classname> - это особенно полезно
586             для некоторых альтернативных маршрутизаторов и помощников видов.
587         </para>
589         <para>
590             Как правило, нет необходимости создавать подклассы
591             фронт-контроллера, если только не нужно добавить новый
592             функционал (например, автозагрузку плагинов или способ
593             определения путей к помощникам действий). Целями, для достижения
594             которых может потребоваться изменение поведения фронт-контроллера,
595             могут быть изменение принципа хранения директорий
596             контроллеров, установка других используемых по умолчанию
597             маршрутизатора и диспетчера и т.д.
598         </para>
599     </sect2>
600 </sect1>
601 <!--
602 vim:se ts=4 sw=4 et: