1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect3 id="zend.controller.router.routes.regex">
4 <title>Zend_Controller_Router_Route_Regex</title>
7 Кроме описанных ранее типов маршрутов - используемого по умолчанию и
8 статического - есть маршруты на регулярных выражениях. Этот маршрут
9 дает больше мощности и гибкости, чем другие типы маршрутов, но
10 ценой некоторой дополнительной сложности. В то же время он должен быть
11 более быстрым, чем стандартный маршрут.
15 Как и в случае стандартного, такой маршрут должен быть
16 проинициализирован с определением маршрута и некоторыми значениями по
17 умолчанию. Давайте в качестве примера создадим маршрут для архива, такой
18 же, как в предыдущих примерах, но на этот раз с использованием маршрута
22 <programlisting language="php"><![CDATA[
23 $route = new Zend_Controller_Router_Route_Regex(
26 'controller' => 'archive',
30 $router->addRoute('archive', $route);
34 Каждый определенный подшаблон регулярного выражения будет внедрен в
35 объект запроса. В нашем примере после успешного сопоставления с
36 <code>http://domain.com/archive/2006</code> результирующий массив
37 значений может выглядеть следующим образом:
40 <programlisting language="php"><![CDATA[
43 'controller' => 'archive',
50 Ведущая и замыкающая косые черты удаляются из URL в маршрутизаторе
51 до сопоставления. Поэтому URL-у
52 <code>http://domain.com/foo/bar/</code> будет соответствовать
53 регулярное выражение <code>foo/bar</code>, но не
54 <code>/foo/bar</code>.
60 Указатели начала и конца строки ('^' и '$' соответственно)
61 автоматически добавляются в начало и конец всех выражений. Поэтому
62 вы не должны использовать их в своих регулярных выражениях, кроме
63 этого, следует передавать строку выражения целиком.
69 Этот класс маршрута использует символ <code>#</code> в качестве
70 ограничителя. Это означает, что нужно экранировать символы хэша
71 ('#'), но не прямой косой черты ('/') в своем определении маршрута.
72 Поскольку символ '#' (называемый анкером) редко передается
73 веб-серверу, вам нечасто придется использовать этот символ в своем
79 Вы можете получать содержимое заданного подшаблона обычным способом:
82 <programlisting language="php"><![CDATA[
83 public function showAction()
85 $request = $this->getRequest();
86 $year = $request->getParam(1); // $year = '2006';
92 Обратите внимание, что ключ является целым числом (1), а не строкой ('1').
97 Этот маршрут не будет работать в точности так же, как и аналогичный ему
98 стандартный маршрут, потому что еще не определено значение по умолчанию
99 для 'year'. Есть еще неочевидная проблема с замыкающей косой чертой,
100 которая остается даже в том случае, если мы объявим значение по
101 умолчанию для 'year' и сделаем подшаблон опциональным. Решение состоит в
102 том, чтобы сделать часть 'year' опциональной вместе с косой чертой, но
103 отлавливать только число:
106 <programlisting language="php"><![CDATA[
107 $route = new Zend_Controller_Router_Route_Regex(
108 'archive(?:/(\d+))?',
111 'controller' => 'archive',
115 $router->addRoute('archive', $route);
119 А теперь давайте обратимся к проблеме, которую вы, должно быть, заметили
120 сами. Использование целочисленных ключей для параметров не является
121 легко управляемым решением и потенциально проблематично в долговременном
122 использовании. Вот тут на сцену выходит третий параметр. Этот параметр
123 является ассоциативным массивом, представляющий соответствие подшаблонов
124 регулярного выражения именованным ключам параметров. Доработаем наш
128 <programlisting language="php"><![CDATA[
129 $route = new Zend_Controller_Router_Route_Regex(
132 'controller' => 'archive',
139 $router->addRoute('archive', $route);
143 Это приведет к тому, что в объект запроса будут добавлены следующие
147 <programlisting language="php"><![CDATA[
150 'controller' => 'archive',
156 Для того, чтобы соответствия работали в любом окружении, они могут быть
157 определены в любом направлении. Ключи массива могут содержать как имена
158 переменных, так и индексы подшаблонов:
161 <programlisting language="php"><![CDATA[
162 $route = new Zend_Controller_Router_Route_Regex(
170 $route = new Zend_Controller_Router_Route_Regex(
179 Ключи подшаблонов должны быть представлены целыми числами.
184 Обратите внимание, что числовой индекс в значениях объекта запроса
185 теперь отсутствует и вместо него присутствует именованная переменная.
186 Конечно, при желании вы можете смешивать числовые и именованные ключи:
189 <programlisting language="php"><![CDATA[
190 $route = new Zend_Controller_Router_Route_Regex(
191 'archive/(\d+)/page/(\d+)',
198 Это приведет к тому, что в объекте запроса будут значения с разными
199 ключами. Например, при URL
200 <code>http://domain.com/archive/2006/page/10</code> результатом будут
204 <programlisting language="php"><![CDATA[
208 'controller' => 'archive',
214 Поскольку регулярные выражения трудно реверсировать, то вам нужно будет
215 подготовить реверсный URL, если хотите использовать хелпер для URL, или
216 даже написать метод этого класса. Реверсный путь представляется строкой,
217 оформленной для использования с функцией sprintf(), и определенной как
218 четвертый параметр конструктора:
221 <programlisting language="php"><![CDATA[
222 $route = new Zend_Controller_Router_Route_Regex(
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 вы можете сделать нечто подобное для решения
243 <programlisting language="php"><![CDATA[
244 $route = new Zend_Controller_Router_Route_Regex(
245 'blog/archive/(\d+)-(.+)\.html',
247 'controller' => 'blog',
254 'blog/archive/%d-%s.html'
256 $router->addRoute('blogArchive', $route);
260 Как вы можете видеть, маршруты Regex дают несравненно большую гибкость
261 по сравнению со стандартными маршрутами.