[MANUAL] English:
[zend.git] / documentation / manual / ru / module_specs / Zend_Controller-Router.xml
blob89adcb42f9d307d8765179c9ab9d936de21053a5
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.controller.router"  xmlns:xi="http://www.w3.org/2001/XInclude">
4     <title>Стандартный маршрутизатор</title>
5     <sect2 id="zend.controller.router.introduction">
6         <title>Введение</title>
7         <para>
8             <classname>Zend_Controller_Router_Rewrite</classname> является стандартным
9             маршрутизатором фреймворка. Маршрутизация - это процесс принятия
10             конечной точки URI (той части URI, которая
11             идет после базового URL) и ее разложения на параметры
12             для определения того, какой контроллер и какое действие этого
13             контроллера должны получить запрос. Значения контроллера,
14             действия и необязательных параметров сохраняются в объекте
15             <classname>Zend_Controller_Request_Http</classname>, который затем
16             обрабатывается диспетчером
17             <classname>Zend_Controller_Dispatcher_Standard</classname>. Маршрутизация
18             производится только один раз – когда вначале
19             получен запрос и до того, как первый контроллер будет запущен.
20         </para>
22         <para>
23             <classname>Zend_Controller_Router_Rewrite</classname> спроектирован для
24             того, чтобы обеспечить функциональность, подобную mod_rewrite,
25             с использованием чистого PHP. Он отчасти основан на маршрутизации,
26             используемой в Ruby on Rails и не требует каких-либо предварительных
27             знаний о перезаписи URL веб-сервером. Он спроектирован для работы с
28             единственным правилом mod_rewrite, пример которого приведен
29             ниже:
30         </para>
32         <programlisting language="php"><![CDATA[
33 RewriteEngine on
34 RewriteRule !\.(js|ico|gif|jpg|png|css|html)$ index.php
35 ]]></programlisting>
37         <para>
38             или (более предпочтительный вариант):
39         </para>
41         <programlisting language="php"><![CDATA[
42 RewriteEngine On
43 RewriteCond %{REQUEST_FILENAME} -s [OR]
44 RewriteCond %{REQUEST_FILENAME} -l [OR]
45 RewriteCond %{REQUEST_FILENAME} -d
46 RewriteRule ^.*$ - [NC,L]
47 RewriteRule ^.*$ index.php [NC,L]
48 ]]></programlisting>
50         <para>
51             Rewrite Router может также использоваться с веб-сервером IIS версии
52             7.0 и ниже, если
53             <ulink url="http://www.isapirewrite.com">Isapi_Rewrite</ulink>
54             был установлен как расширение Isapi со следующими правилами
55             перезаписи:
56         </para>
58         <programlisting language="php"><![CDATA[
59 RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css|html)$)[\w\%]*$)? /index.php [I]
60 ]]></programlisting>
62         <note>
63             <title>IIS Isapi_Rewrite</title>
64             <para>
65                 Если используется IIS, то <varname>$_SERVER['REQUEST_URI']</varname>
66                 не будет определен, либо будет установлен как пустая
67                 строка. В этом случае
68                 <classname>Zend_Controller_Request_Http</classname> попытается
69                 использовать <varname>$_SERVER['HTTP_X_REWRITE_URL']</varname>,
70                 значение которого устанавливается расширением Isapi_Rewrite.
71             </para>
72         </note>
74         <para>
75             IIS 7.0 имеет свой собственный модуль перезаписи URL,
76             и он может быть сконфигурирован следующим образом:
77         </para>
79         <programlisting language="xml"><![CDATA[
80 <?xml version="1.0" encoding="UTF-8"?>
81 <configuration>
82      <system.webServer>
83          <rewrite>
84              <rules>
85                  <rule name="Imported Rule 1" stopProcessing="true">
86                      <match url="^.*$" />
87                      <conditions logicalGrouping="MatchAny">
88                          <add input="{REQUEST_FILENAME}"
89                              matchType="IsFile" pattern=""
90                              ignoreCase="false" />
91                          <add input="{REQUEST_FILENAME}"
92                              matchType="IsDirectory"
93                              pattern="" ignoreCase="false" />
94                      </conditions>
95                      <action type="None" />
96                  </rule>
97                  <rule name="Imported Rule 2" stopProcessing="true">
98                      <match url="^.*$" />
99                      <action type="Rewrite" url="index.php" />
100                  </rule>
101              </rules>
102          </rewrite>
103      </system.webServer>
104 </configuration>
105 ]]></programlisting>
107         <para>
108             Если используется Lighttpd, то корректным будет следующее
109             правило перезаписи:
110         </para>
112         <programlisting language="lighttpd"><![CDATA[
113 url.rewrite-once = (
114     ".*\?(.*)$" => "/index.php?$1",
115     ".*\.(js|ico|gif|jpg|png|css|html)$" => "$0",
116     "" => "/index.php"
118 ]]></programlisting>
119     </sect2>
121     <sect2 id="zend.controller.router.usage">
122         <title>Использование маршрутизатора</title>
124         <para>
125             Для того, чтобы правильно использовать маршрутизатор, вы должны
126             инстанцировать его, добавить пользовательские маршруты, и внедрить
127             его во фронт-контроллер. Следующий код иллюстрирует эту процедуру:
128         </para>
130         <programlisting language="php"><![CDATA[
131 // Создание маршрутизатора
133 $router = $ctrl->getRouter(); // по умолчанию возвращает rewrite router
134 $router->addRoute(
135     'user',
136     new Zend_Controller_Router_Route('user/:username',
137                                      array('controller' => 'user',
138                                            'action' => 'info'))
140 ]]></programlisting>
141     </sect2>
143     <sect2 id="zend.controller.router.basic">
144         <title>Базовые операции Rewrite Router</title>
146         <para>
147             Сущностью RewriteRouter (перезаписывающий маршрутизатор) является
148             определение пользовательских маршрутов. Маршруты добавляются
149             посредством вызовом метода <code>addRoute()</code> и передачей ему
150             экземпляра класса, реализующего
151             <classname>Zend_Controller_Router_Route</classname>. Например:
152         </para>
154         <programlisting language="php"><![CDATA[
155 $router->addRoute('user',
156                   new Zend_Controller_Router_Route('user/:username'));
157 ]]></programlisting>
159         <para>
160             Rewrite Router поставляется вместе с шестью базовыми типами
161             маршрутов (один из которых является специальным):
162         </para>
164         <itemizedlist mark="opencircle">
165             <listitem><para>
166                 <xref linkend="zend.controller.router.routes.standard" />
167             </para></listitem>
168             <listitem><para>
169                 <xref linkend="zend.controller.router.routes.static" />
170             </para></listitem>
171             <listitem><para>
172                 <xref linkend="zend.controller.router.routes.regex" />
173             </para></listitem>
174             <listitem><para>
175                 <xref linkend="zend.controller.router.routes.hostname" />
176             </para></listitem>
177             <listitem><para>
178                 <xref linkend="zend.controller.router.routes.chain" />
179             </para></listitem>
180             <listitem><para>
181                 <xref linkend="zend.controller.router.default-routes" /> *
182              </para></listitem>
183         </itemizedlist>
185         <para>
186             Маршруты могут использоваться несколько раз для создания цепочки или
187             пользовательской схемы маршрутизации в приложении. Вы можете
188             использовать любое количество маршрутов в любой конфигурации, за
189             исключением маршрута Module, который предпочтительно должен
190             использоваться один раз и, возможно, как наиболее общий маршрут
191             (например, в качестве используемого по умолчанию). Каждый маршрут
192             будет в подробностях описан ниже.
193         </para>
195         <para>
196             Первым параметром метода <code>addRoute()</code> является имя
197             маршрута. Он используется в качестве идентификатора для получения
198             маршрутов из маршрутизатора (например, в целях генерации URL).
199             Вторым параметром является сам маршрут.
200         </para>
202         <note>
203             <para>
204                 Наиболее часто имя маршрута используется через хелпер для URL
205                 компоненты <classname>Zend_View</classname>:
206             </para>
208             <programlisting language="php"><![CDATA[
209 <a href=
210 "<?php echo $this->url(array('username' => 'martel'), 'user') ?>">Martel</a>
211 ]]></programlisting>
213             <para>
214                В результате значением атрибута href будет
215                <code>user/martel</code>.
216             </para>
217         </note>
219         <para>
220             Маршрутизация - простой процесс итерации по всем предоставленным
221             маршрутам и сопоставления их определений с текущим URI запроса.
222             Когда найдено соответствие, то из объекта маршрута возвращаются
223             значения переменных и добавляются в объект
224             <classname>Zend_Controller_Request</classname> для дальнейшего использования в
225             диспетчере и пользовательских контроллерах. Если соответствие не
226             найдено, то проверяется следующий маршрут в цепочке.
227         </para>
229         <para>
230             Если нужно определить выбранный маршрут,
231             то можно использовать метод <code>getCurrentRouteName()</code>,
232             он возвращает идентификатор, который использовался при регистрации
233             маршрута в маршрутизаторе. Если требуется получить объект,
234             то используйте <code>getCurrentRoute()</code>.
235         </para>
237         <note>
238             <title>Обратный порядок сопоставления</title>
239             <para>
240                 Маршруты сопоставляются в обратном порядке, поэтому
241                 удостоверьтесь, что наиболее общие маршруты определены
242                 первыми.
243             </para>
244         </note>
246         <note>
247             <title>Возвращаемые значения</title>
248             <para>
249                 Значения, возвращаемые при маршрутизации, получаются из
250                 параметров URL или определенных пользователем значений по
251                 умолчанию. Эти переменные позднее могут быть позднее получены
252                 через методы <code>Zend_Controller_Request::getParam()</code>
253                 и <code>Zend_Controller_Action::_getParam()</code>
254             </para>
255         </note>
257         <para>
258             Есть три специальные переменные, которые могут использоваться в
259             маршрутах: 'module', 'controller' и 'action'. Эти
260             переменные используются диспетчером <classname>Zend_Controller_Dispatcher</classname>
261             для нахождения контроллера и действия, которым передается
262             управление.
263         </para>
265         <note>
266             <title>Специальные переменные</title>
267             <para>
268                 Имена этих переменных могут быть другими, если вы измените их
269                 через методы <code>setControllerKey</code> и
270                 <code>setActionKey</code>.
271             </para>
272         </note>
274     </sect2>
276     <sect2 id="zend.controller.router.default-routes">
277         <title>Маршруты, используемые по умолчанию</title>
279         <para>
280             <classname>Zend_Controller_Router_Rewrite</classname> изначально
281             сконфигурирован с одним маршрутом по умолчанию, который будет
282             соответствовать URI вида <code>контроллер/действие</code>. Кроме
283             того, в качестве первого элемента пути может быть указано имя
284             модуля, это позволяет использовать URI вида
285             <code>модуль/контроллер/действие</code>.
286             Этот маршрут будет также соответствовать любым дополнительным
287             параметрам, по умолчанию добавляемым в конец URI -
288             <code>контроллер/действие/переменная1/значение1/переменная2/значение2</code>.
289         </para>
291         <para>
292             Некоторые примеры того, чему будут соответствовать такие маршруты:
293         </para>
295         <programlisting language="php"><![CDATA[
296 // Допустим, есть следующие настройки:
297 $ctrl->setControllerDirectory(
298     array(
299         'default' => '/path/to/default/controllers',
300         'news'    => '/path/to/news/controllers',
301         'blog'    => '/path/to/blog/controllers'
302     )
305 Только модуль:
306 http://example/news
307     module == news
309 Если модуль не найден, то считается, что это имя контроллера:
310 http://example/foo
311     controller == foo
313 Модуль + контроллер:
314 http://example/blog/archive
315     module     == blog
316     controller == archive
318 Модуль + контроллер + действие:
319 http://example/blog/archive/list
320     module     == blog
321     controller == archive
322     action     == list
324 Модуль + контроллер + действие + параметры:
325 http://example/blog/archive/list/sort/alpha/date/desc
326     module     == blog
327     controller == archive
328     action     == list
329     sort       == alpha
330     date       == desc
331 ]]></programlisting>
333         <para>
334             Маршрутом, используемым по умолчанию, является объект
335             <classname>Zend_Controller_Router_Route_Module</classname>, сохраненный в
336             RewriteRouter под именем (индексом) 'default'. Он создается
337             приблизительно следующим образом:
338         </para>
340         <programlisting language="php"><![CDATA[
341 $compat = new Zend_Controller_Router_Route_Module(array(),
342                                                   $dispatcher,
343                                                   $request);
344 $this->addRoute('default', $compat);
345 ]]></programlisting>
347         <para>
348             Если вы не хотите использовать этот маршрут по умолчанию в своей
349             схеме маршрутизации, то можете переопределить его путем создания
350             собственного маршрута по умолчанию (т.е. сохранения его под именем
351             'default') или полностью удалить его через метод
352             <code>removeDefaultRoutes()</code>:
353         </para>
355         <programlisting language="php"><![CDATA[
356 // Удаление всех маршрутов по умолчанию
357 $router->removeDefaultRoutes();
358 ]]></programlisting>
360     </sect2>
362     <sect2 id="zend.controller.router.rewritebase">
363         <title>Базовый URL и поддиректории</title>
365         <para>
366             RewriteRouter может использоваться в поддиректориях (например,
367             <code>http://domain.com/~user/application-root/</code>), в этом
368             случае базовый URL приложения (<code>/~user/application-root</code>)
369             должен автоматически определяться в объекте
370             <classname>Zend_Controller_Request_Http</classname> и соответствующим образом
371             использоваться.
372         </para>
374         <para>
375             Если базовый URL определяется некорректно, то вы можете
376             переопределить его через метод <code>setBaseUrl()</code> объекта
377             <classname>Zend_Controller_Request_Http</classname> (см.
378             <xref linkend="zend.controller.request.http.baseurl" />):
379         </para>
381         <programlisting language="php"><![CDATA[
382 $request->setBaseUrl('/~user/application-root/');
383 ]]></programlisting>
385     </sect2>
387     <sect2 id="zend.controller.router.global.parameters">
388         <title>Глобальные параметры</title>
390         <para>
391             Используя метод <code>setGlobalParam</code>, вы можете устанавливать
392             глобальные параметры в маршрутизаторе, которые будут автоматически
393             подставляться в маршрут при сборке. Если был установлен глобальный
394             параметр, но при сборке тот же параметр был передан напрямую,
395             то переданное значение параметра заменяет собой глобальное.
396             Вы можете устанавливать глобальный параметр следующим образом:
397         </para>
399         <programlisting language="php"><![CDATA[
400 $router->setGlobalParam('lang', 'en');
401 ]]></programlisting>
402     </sect2>
404     <sect2 id="zend.controller.router.routes">
405         <title>Типы маршрутов</title>
406         <xi:include href="Zend_Controller-Router-Route.xml">
407             <xi:fallback><xi:include href="../../en/module_specs/Zend_Controller-Router-Route.xml" /></xi:fallback>
408         </xi:include>
409         <xi:include href="Zend_Controller-Router-Route-Static.xml">
410             <xi:fallback><xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Static.xml" /></xi:fallback>
411         </xi:include>
412         <xi:include href="Zend_Controller-Router-Route-Regex.xml">
413             <xi:fallback><xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Regex.xml" /></xi:fallback>
414         </xi:include>
415         <xi:include href="Zend_Controller-Router-Route-Hostname.xml">
416             <xi:fallback><xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Hostname.xml" /></xi:fallback>
417         </xi:include>
418         <xi:include href="Zend_Controller-Router-Route-Chain.xml">
419             <xi:fallback><xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Chain.xml" /></xi:fallback>
420         </xi:include>
421     </sect2>
423     <sect2 id="zend.controller.router.add-config">
424         <title>Использование Zend_Config вместе с RewriteRouter</title>
426         <para>
427             Иногда может быть более удобным обновлять конфигурационный файл
428             с новыми маршрутами, чем изменять код. Это возможно благодаря методу
429             <code>addConfig()</code>. В сущности, вы создаете конфигурацию,
430             совместимую с <classname>Zend_Config</classname>, считываете ее в своем коде и
431             передаете RewriteRouter.
432         </para>
434         <para>
435             В качестве примера рассмотрим следующий INI-файл:
436         </para>
438         <programlisting language="php"><![CDATA[
439 [production]
440 routes.archive.route = "archive/:year/*"
441 routes.archive.defaults.controller = archive
442 routes.archive.defaults.action = show
443 routes.archive.defaults.year = 2000
444 routes.archive.reqs.year = "\d+"
446 routes.news.type = "Zend_Controller_Router_Route_Static"
447 routes.news.route = "news"
448 routes.news.defaults.controller = "news"
449 routes.news.defaults.action = "list"
451 routes.archive.type = "Zend_Controller_Router_Route_Regex"
452 routes.archive.route = "archive/(\d+)"
453 routes.archive.defaults.controller = "archive"
454 routes.archive.defaults.action = "show"
455 routes.archive.map.1 = "year"
456 ; ИЛИ: routes.archive.map.year = 1
457 ]]></programlisting>
459         <para>
460             Этот INI-файл может быть затем прочитан в объект
461             <classname>Zend_Config</classname> как показано ниже:
462         </para>
464         <programlisting language="php"><![CDATA[
465 $config = new Zend_Config_Ini('/path/to/config.ini', 'production');
466 $router = new Zend_Controller_Router_Rewrite();
467 $router->addConfig($config, 'routes');
468 ]]></programlisting>
470         <para>
471             В примере выше мы говорим маршрутизатору, чтобы он использовал
472             раздел 'routes' в файле INI для своих маршрутов. Ключ первого уровня
473             в этом разделе используется для определения имени маршрута, в
474             примере выше определяются маршруты 'archive' и
475             'news'. Каждый маршрут требует, как минимум, запись 'route' и
476             одну или более записей 'defaults'; опционально может быть одна
477             или более записей 'reqs' (сокращение от 'required'). Все это
478             соответствует трем аргументам, передаваемым объекту
479             <classname>Zend_Controller_Router_Route_Interface</classname>.
480             Опция с ключом 'type' может использоваться для определения класса,
481             используемого для данного маршрута; по умолчанию используется
482             класс <classname>Zend_Controller_Router_Route</classname>. В примере выше
483             для маршрута 'news' должен использоваться класс
484             <classname>Zend_Controller_Router_Route_Static</classname>.
485         </para>
486     </sect2>
488     <sect2 id="zend.controller.router.subclassing">
489         <title>Создание подклассов маршрутизатора</title>
491         <para>
492             Стандартный RewriteRouter создан с тем, чтобы предоставлять полный
493             набор тех функциональных возможностей, которые могут вам
494             понадобиться. Как правило, вам нужно будет только создать новый тип
495             маршрута для того, чтобы получить новый или измененный функционал
496             сверх уже существующих типов маршрутов.
497         </para>
499         <para>
500             В какой-то момент вы можете захотеть использовать другую парадигму
501             маршрутизации. Интерфейс
502             <classname>Zend_Controller_Router_Interface</classname> дает минимальную
503             информацию, необходимую для создания маршрута и содержит всего один
504             метод.
505         </para>
507         <programlisting language="php"><![CDATA[
508 interface Zend_Controller_Router_Interface
510   /**
511    * @param  Zend_Controller_Request_Abstract $request
512    * @throws Zend_Controller_Router_Exception
513    * @return Zend_Controller_Request_Abstract
514    */
515   public function route(Zend_Controller_Request_Abstract $request);
517 ]]></programlisting>
519         <para>
520             Маршрутизация производится только один раз - когда в систему
521             поступил первый запрос. Назначение маршрутизатора состоит в
522             определении контроллера, действия и опциональных параметров,
523             основываясь на переменных запроса, и установке их в запросе. Затем
524             объект запроса передается диспетчеру. Если не найден соответствующий
525             маршрут, то маршрутизатор не должен ничего делать с объектом
526             запроса.
527         </para>
528     </sect2>
529 </sect1>
530 <!--
531 vim:se ts=4 sw=4 et: