[ZF-10089] Zend_Log
[zend.git] / documentation / manual / ru / module_specs / Zend_Controller-Router-Route-Regex.xml
blobe1c26cf172bbd47c43187b73b3584842ee372752
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect3 id="zend.controller.router.routes.regex">
4     <title>Zend_Controller_Router_Route_Regex</title>
6     <para>
7         Кроме описанных ранее типов маршрутов - используемого по умолчанию и
8         статического - есть маршруты на регулярных выражениях. Этот маршрут
9         дает больше мощности и гибкости, чем другие типы маршрутов, но
10         ценой некоторой дополнительной сложности. В то же время он должен быть
11         более быстрым, чем стандартный маршрут.
12     </para>
14     <para>
15         Как и в случае стандартного, такой маршрут должен быть
16         проинициализирован с определением маршрута и некоторыми значениями по
17         умолчанию. Давайте в качестве примера создадим маршрут для архива, такой
18         же, как в предыдущих примерах, но на этот раз с использованием маршрута
19         Regex:
20     </para>
22     <programlisting language="php"><![CDATA[
23 $route = new Zend_Controller_Router_Route_Regex(
24     'archive/(\d+)',
25     array(
26         'controller' => 'archive',
27         'action'     => 'show'
28     )
30 $router->addRoute('archive', $route);
31 ]]></programlisting>
33     <para>
34         Каждый определенный подшаблон регулярного выражения будет внедрен в
35         объект запроса. В нашем примере после успешного сопоставления с
36         <code>http://domain.com/archive/2006</code> результирующий массив
37         значений может выглядеть следующим образом:
38     </para>
40     <programlisting language="php"><![CDATA[
41 $values = array(
42     1            => '2006',
43     'controller' => 'archive',
44     'action'     => 'show'
46 ]]></programlisting>
48     <note>
49         <para>
50             Ведущая и замыкающая косые черты удаляются из URL в маршрутизаторе
51             до сопоставления. Поэтому URL-у
52             <code>http://domain.com/foo/bar/</code> будет соответствовать
53             регулярное выражение <code>foo/bar</code>, но не
54             <code>/foo/bar</code>.
55         </para>
56     </note>
58     <note>
59         <para>
60             Указатели начала и конца строки ('^' и '$' соответственно)
61             автоматически добавляются в начало и конец всех выражений. Поэтому
62             вы не должны использовать их в своих регулярных выражениях, кроме
63             этого, следует передавать строку выражения целиком.
64         </para>
65     </note>
67     <note>
68         <para>
69             Этот класс маршрута использует символ <code>#</code> в качестве
70             ограничителя. Это означает, что нужно экранировать символы хэша
71             ('#'), но не прямой косой черты ('/') в своем определении маршрута.
72             Поскольку символ '#' (называемый анкером) редко передается
73             веб-серверу, вам нечасто придется использовать этот символ в своем
74             регулярном выражении.
75         </para>
76     </note>
78     <para>
79         Вы можете получать содержимое заданного подшаблона обычным способом:
80     </para>
82     <programlisting language="php"><![CDATA[
83 public function showAction()
85     $request = $this->getRequest();
86     $year    = $request->getParam(1); // $year = '2006';
88 ]]></programlisting>
90     <note>
91         <para>
92             Обратите внимание, что ключ является целым числом (1), а не строкой ('1').
93         </para>
94     </note>
96     <para>
97         Этот маршрут не будет работать в точности так же, как и аналогичный ему
98         стандартный маршрут, потому что еще не определено значение по умолчанию
99         для 'year'. Есть еще неочевидная проблема с замыкающей косой чертой,
100         которая остается даже в том случае, если мы объявим значение по
101         умолчанию для 'year' и сделаем подшаблон опциональным. Решение состоит в
102         том, чтобы сделать часть 'year' опциональной вместе с косой чертой, но
103         отлавливать только число:
104     </para>
106     <programlisting language="php"><![CDATA[
107 $route = new Zend_Controller_Router_Route_Regex(
108     'archive(?:/(\d+))?',
109     array(
110         1            => '2006',
111         'controller' => 'archive',
112         'action'     => 'show'
113     )
115 $router->addRoute('archive', $route);
116 ]]></programlisting>
118     <para>
119         А теперь давайте обратимся к проблеме, которую вы, должно быть, заметили
120         сами. Использование целочисленных ключей для параметров не является
121         легко управляемым решением и потенциально проблематично в долговременном
122         использовании. Вот тут на сцену выходит третий параметр. Этот параметр
123         является ассоциативным массивом, представляющий соответствие подшаблонов
124         регулярного выражения именованным ключам параметров. Доработаем наш
125         простой пример:
126     </para>
128     <programlisting language="php"><![CDATA[
129 $route = new Zend_Controller_Router_Route_Regex(
130     'archive/(\d+)',
131     array(
132         'controller' => 'archive',
133         'action' => 'show'
134     ),
135     array(
136         1 => 'year'
137     )
139 $router->addRoute('archive', $route);
140 ]]></programlisting>
142     <para>
143         Это приведет к тому, что в объект запроса будут добавлены следующие
144         значения:
145     </para>
147     <programlisting language="php"><![CDATA[
148 $values = array(
149     'year'       => '2006',
150     'controller' => 'archive',
151     'action'     => 'show'
153 ]]></programlisting>
155     <para>
156         Для того, чтобы соответствия работали в любом окружении, они могут быть
157         определены в любом направлении. Ключи массива могут содержать как имена
158         переменных, так и индексы подшаблонов:
159     </para>
161     <programlisting language="php"><![CDATA[
162 $route = new Zend_Controller_Router_Route_Regex(
163     'archive/(\d+)',
164     array( ... ),
165     array(1 => 'year')
168 // ИЛИ
170 $route = new Zend_Controller_Router_Route_Regex(
171     'archive/(\d+)',
172     array( ... ),
173     array('year' => 1)
175 ]]></programlisting>
177     <note>
178         <para>
179             Ключи подшаблонов должны быть представлены целыми числами.
180         </para>
181     </note>
183     <para>
184         Обратите внимание, что числовой индекс в значениях объекта запроса
185         теперь отсутствует и вместо него присутствует именованная переменная.
186         Конечно, при желании вы можете смешивать числовые и именованные ключи:
187     </para>
189     <programlisting language="php"><![CDATA[
190 $route = new Zend_Controller_Router_Route_Regex(
191     'archive/(\d+)/page/(\d+)',
192     array( ... ),
193     array('year' => 1)
195 ]]></programlisting>
197     <para>
198         Это приведет к тому, что в объекте запроса будут значения с разными
199         ключами. Например, при URL
200         <code>http://domain.com/archive/2006/page/10</code> результатом будут
201         следующие значения:
202     </para>
204     <programlisting language="php"><![CDATA[
205 $values = array(
206     'year'       => '2006',
207     2            => 10,
208     'controller' => 'archive',
209     'action'     => 'show'
211 ]]></programlisting>
213     <para>
214         Поскольку регулярные выражения трудно реверсировать, то вам нужно будет
215         подготовить реверсный URL, если хотите использовать хелпер для URL, или
216         даже написать метод этого класса. Реверсный путь представляется строкой,
217         оформленной для использования с функцией sprintf(), и определенной как
218         четвертый параметр конструктора:
219     </para>
221     <programlisting language="php"><![CDATA[
222 $route = new Zend_Controller_Router_Route_Regex(
223     'archive/(\d+)',
224     array( ... ),
225     array('year' => 1),
226     'archive/%s'
228 ]]></programlisting>
230     <para>
231         Все это можно реализовать через объект стандартного маршрута, поэтому вы
232         спросите - какие преимущества дает использование маршрута Regex? Главным
233         образом, он позволяет описывать любые типы URL без всяких ограничений.
234         Предположим, у вас есть свой блог, вы хотите создавать URL вида
235         <code>http://domain.com/blog/archive/01-Using_the_Regex_Router.html</code>
236         и должны разлагать последний элемент пути
237         <code>01-Using_the_Regex_Router.html</code> на ID статьи и ее
238         заголовок/описание. Это невозможно реализовать с помощью стандартного
239         маршрута. С маршрутом Regex вы можете сделать нечто подобное для решения
240         этой задачи:
241     </para>
243     <programlisting language="php"><![CDATA[
244 $route = new Zend_Controller_Router_Route_Regex(
245     'blog/archive/(\d+)-(.+)\.html',
246     array(
247         'controller' => 'blog',
248         'action'     => 'view'
249     ),
250     array(
251         1 => 'id',
252         2 => 'description'
253     ),
254     'blog/archive/%d-%s.html'
256 $router->addRoute('blogArchive', $route);
257 ]]></programlisting>
259     <para>
260         Как вы можете видеть, маршруты Regex дают несравненно большую гибкость
261         по сравнению со стандартными маршрутами.
262     </para>
263 </sect3>
264 <!--
265 vim:se ts=4 sw=4 et: