# Zend_Controller_Router_Route

`Zend_Controller_Router_Route` - стандартный маршрут фреймворка. Он сочетает в себе легкость использования и гибкость определения маршрутов. Каждый маршрут состоит в основном из карты URL (статических и динамических частей (переменных)), и может быть инициализирован со значениями по умолчанию и требованиями к переменным.

Давайте представим себе некое приложение, в котором нужно разместить несколько информационных страниц об авторах. Мы хотим, чтобы адрес `http://domain.com/author/martel` вел на страницу с информацией об авторе с именем "martel". Маршрут для обеспечения такой функциональности может выглядеть следующим образом:

    $route = new Zend_Controller_Router_Route(
        'author/:username',
        array(
            'controller' => 'profile',
            'action'     => 'userinfo'
        )
    );

    $router->addRoute('user', $route);

Первый параметр конструктора `Zend_Controller_Router_Route` - определение маршрута, которое будет сопоставляться с URL. Определения маршрутов содержат статические и динамические части, разделенные символом косой черты ('/'). Статические части являются обычным текстом: `author`. Динамические части, называемые переменными, помечаются знаком двоеточия в начале имени переменной: `:username`.

## Использование символов

Текущая реализация позволяет использовать любые (за исключением косой черты) символы в идентификаторе переменной, но сильно рекомендуется использовать в них только символы, допустимые для переменных в php. Есть вероятность, что в будущем реализация изменится, и это может вызвать скрытые ошибки в вашем коде.

Этот маршрут должен сработать, когда вы вводите `http://domain.com/author/martel` в своем броузере, в этом случае все его переменные будут добавлены в объект `Zend_Controller_Request` и будут доступны в вашем контроллере `ProfileController`. Переменные, возвращаемые в этом примере, могут быть представленые в виде следующего массива пар ключ/значение:

    $values = array(
        'username'   => 'martel',
        'controller' => 'profile',
        'action'     => 'userinfo'
    );

Затем `Zend_Controller_Dispatcher_Standard` должен вызвать метод `userinfoAction()` вашего класса `ProfileController` (используется модуль по умолчанию), основываясь на этих значениях. Вы сможете получать эти переменные через методы `Zend_Controller_Action::_getParam()` или `Zend_Controller_Request::getParam()`.

    public function userinfoAction()
    {
        $request = $this->getRequest();
        $username = $request->getParam('username');

        $username = $this->_getParam('username');
    }

Определение маршрута может содержать в себе еще один специальный символ (метасимвол), представленный символом '*'. Он используется для сбора параметров, как в маршруте Module, используемом по умолчанию (пары переменная => значение, определенные в URI). Следующий маршрут приближенно воспроизводит поведение маршрута Module:

    $route = new Zend_Controller_Router_Route(
        ':module/:controller/:action/*',
        array('module' => 'default')
    );
    $router->addRoute('default', $route);

## Значения переменных по умолчанию

Любая переменная в маршруте может иметь значение по умолчанию, для этого используется второй параметр конструктора `Zend_Controller_Router_Route`. Этот параметр является массивом с ключами, представляющими имена переменных, и со значениями в качестве значений переменных по умолчанию:

    $route = new Zend_Controller_Router_Route(
        'archive/:year',
        array('year' => 2006)
    );
    $router->addRoute('archive', $route);

Маршрут выше будет соответствовать URL-ам `http://domain.com/archive/2005` и `http://example.com/archive`. В последнем случае переменная year будет иметь начальное значение по умолчанию 2006.

В этом примере переменная `year` будет добавлена в объект запроса. Поскольку не была предоставлена информация для маршрутизации (не определены параметры `controller` и `action`), то управление будет передано контроллеру и методу действия, используемым по умолчанию (оба определены в `Zend_Controller_Dispatcher_Abstract`). Для того, чтобы сделать этот пример более полезным, нужно передать действительные контроллер и действие в качестве значений по умолчанию:

    $route = new Zend_Controller_Router_Route(
        'archive/:year',
        array(
            'year'       => 2006,
            'controller' => 'archive',
            'action'     => 'show'
        )
    );
    $router->addRoute('archive', $route);

В результате будет вызван метод `showAction()` класса `ArchiveController`.

## Требования к переменным

Можно передать конструктору `Zend_Controller_Router_Route` третий параметр, в котором установлены требования к переменным. Они определяются как части регулярных выражений:

    $route = new Zend_Controller_Router_Route(
        'archive/:year',
        array(
            'year'       => 2006,
            'controller' => 'archive',
            'action'     => 'show'
        ),
        array('year' => '\d+')
    );
    $router->addRoute('archive', $route);

В случае маршрута, определенного таким образом, маршрутизатор будет считать URL соответствующим ему только если переменная year содержит числовые данные - например, `http://domain.com/archive/2345`. URL вида `http://example.com/archive/test` не будет соответствовать этому маршруту, вместо этого будет произведен переход к следующему маршруту в цепочке.

## Переводимые сегменты

Стандартный маршрут поддерживает переводимые сегменты. Для того, чтобы использовать эту возможность, нужно как минимум указать, какой переводчик (экземпляр `Zend_Translate`) должен использоваться - одним из следующих способов:

- Поместить его в реестр с ключом `Zend_Translate`.

- Установить через статический метод `Zend_Controller_Router_Route::setDefaultTranslator()`.

- Передать его конструктору в качестве четвертого параметра.

По умолчанию используется локаль, указанная в экземпляре `Zend_Translate`. Для того, чтобы переопределить ее, вы можете установить ее значение (экземпляр `Zend_Locale` или строка с локалью) одним из следующих способов:

- Поместить ее в реестр с ключом `Zend_Locale`.

- Установить через статический метод `Zend_Controller_Router_Route::setDefaultLocale()`.

- Передать ее конструктору в качестве пятого параметра.

- Передать ее как параметр `@locale` методу `assemble()`.

Переводимые сегменты делятся на два типа. У статических сегментов в начале ставится один символ `@`, они будут переведены в соответствии текущей локалью при сборке URL и преобразованы обратно в идентификатор сообщения при сопоставлении URL с маршрутом. У динамических сегментов в начале ставится `:@`. При сборке URL данный параметр будет переведен и результат перевода будет добавлен на его место. При сопоставлении переведенный параметр из URL будет преобразован обратно в идентификатор сообщения.

### Идентификаторы сообщений и отдельный языковый файл

Может случайно получиться так, что идентификатор сообщения, который вы собираетесь использовать в одном из своих маршрутов, уже используется в ваших скриптах вида или где-то еще. Для того, чтобы иметь полный контроль над вашими URL-ами, следует использовать отдельный языковый файл для сообщений, используемых в маршруте.

Следующий пример демонстрирует наиболее простой способ подготовки стандартного маршрута с использованием переводимых сегментов:

    // Подготовка переводчика
    $translator = new Zend_Translate('array', array(), 'en');
    $translator->addTranslation(array('archive' => 'archiv',
                                      'year'    => 'jahr',
                                      'month'   => 'monat',
                                      'index'   => 'uebersicht'),
                                'de');

    // Установка текущей локали для переводчика
    $translator->setLocale('en');

    // Установка его в качестве используемого по умолчанию для маршрутов
    Zend_Controller_Router_Route::setDefaultTranslator($translator);

Этот пример демонстрирует использование статических сегментов:

    // Создание маршрута
    $route = new Zend_Controller_Router_Route(
        '@archive',
        array(
            'controller' => 'archive',
            'action'     => 'index'
        )
    );
    $router->addRoute('archive', $route);

    // Сборка URL в локали, используемой по умолчанию: archive
    $route->assemble(array());

    // Сборка URL в немецкой локали: archiv
    $route->assemble(array());

Вы можете использовать динамические сегменты для создания переведенных версий как в случае использования маршрутов основанных на модулях:

    // Создание маршрута
    $route = new Zend_Controller_Router_Route(
        ':@controller/:@action/*',
        array(
            'controller' => 'index',
            'action'     => 'index'
        )
    );
    $router->addRoute('archive', $route);

    // Сборка URL в локали, используемой по умолчанию: archive/index/foo/bar
    $route->assemble(array('controller' => 'archive', 'foo' => 'bar'));

    // Сборка URL в немецкой локали: archiv/uebersicht/foo/bar
    $route->assemble(array('controller' => 'archive', 'foo' => 'bar'));

Вы можете также комбинировать статические и динамические сегменты:

    // Создание маршрута
    $route = new Zend_Controller_Router_Route(
        '@archive/:@mode/:value',
        array(
            'mode'       => 'year'
            'value'      => 2005,
            'controller' => 'archive',
            'action'     => 'show'
        ),
        array('mode'  => '(month|year)'
              'value' => '\d+')
    );
    $router->addRoute('archive', $route);

    // Сборка URL в локали, используемой по умолчанию: archive/month/5
    $route->assemble(array('mode' => 'month', 'value' => '5'));

    // Сборка URL в немецкой локали: archiv/monat/5
    $route->assemble(array('mode' => 'month', 'value' => '5', '@locale' => 'de'));