Роутинг

Содержание...

Все HTTP-запросы, попадающие в адресное пространство фреймворка (т. е. запросы по URL, начинающиеся с http://{ИМЯ_ДОМЕНА}/{ПУТЬ_К_ФРЕЙМВОРКУ}/*) направляются с помощью инструкций mod_rewrite на обработку во фронт-контроллер Вебасиста — файл index.php, расположенный в корневом каталоге фреймворка и выполняющий функции диспетчера запросов.

Фронт-контроллер анализирует URL запроса и на основании правил маршрутизации вызывает соответствующее приложение для дальнейшей обработки запроса. Маршрутизация для фронтенда настраивается на двух уровнях:

  1. Общесистемная маршрутизация (обязательный уровень конфигурации);
  2. Маршрутизация внутри приложения (опциональный уровень конфигурации).

Общесистемная маршрутизация

Общесистемная маршрутизация распределяет адресное пространство фронтенда между приложениями. Например, маршрутизация может быть настроена таким образом, что запросы по адресам, начинающимся с http://{ИМЯ_ДОМЕНА}/{ПУТЬ_К_ФРЕЙМВОРКУ}/news/, обрабатываются приложением «Блог», а запросы, начинающиеся с http://{ИМЯ_ДОМЕНА}/{ПУТЬ_К_ФРЕЙМВОРКУ}/photos/, обрабатываются приложением «Фото».

Параметры системной маршрутизации содержатся в файле wa-config/routing.php. Синтаксис конфигурации:

<?php

return array(
    'mydomain.ru' => array(
        0 => array(
            'url' => 'news/*',
            'app' => 'blog'
        ),
        1 => array(
            'url' => 'photos/*',
            'app' => 'photos',
        ),
        2 => array(
            'url' => '*',
            'app' => 'site'
        )
    ),
    'myotherdomain.ru' => array(
        0 => array(
            'url' => 'about/*',
            'app' => 'site'
        ),
        1 => array(
            'url' => 'terms-of-service/*',
            'app' => 'site'
        ),
        2 => array(
            'url' => 'guestbook/*',
            'app' => 'guestbook',
            'module' => 'frontend'
        ),
        3 => array(
            'url' => '*',
            'app' => 'shop'
        )
    )
);

Конфигурируемые параметры:

Параметры общесистемной маршрутизации задаются при настройке системы, доступны для дальнейшего изменения, не зависят от внутренней логики приложений и не влияют на неё.

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

Псевдонимы доменов

Фреймворк предоставляет простую возможность добавления псевдонимов (alias) для доменных имен — зеркал сайтов. Псеводнимы настраиваются в общем файле настройки маршрутизации wa-config/routing.php. Для псеводнимов в качестве значения вместо массива с правилами маршрутизации указывается строка с именем домена, правила маршрутизации которого должны быть описаны в этом же файле и которые будут использованы для псеводнима:

<?php

return array(
    'myaliasdomain.ru' => 'mydomain.ru',
    'myaliasdomain.com' => 'mydomain.ru',
    'xn--80aaarjpej1aqpo.xn--p1ai' => 'mydomain.ru', // для кириллического домена необходимо указать его punycode-версию (http://ru.wikipedia.org/wiki/Punycode)
    'mydomain.ru' => array(
        // ... правила маршрутизации, как в примере выше
    )
);

Псеводним использует правила маршрутизации основного домена, для которого он настроен. Если содержимое сайта-псеводнима полностью повторяет (копирует) содержимое основного домена, то это может привести к непредвиденным результатами индексации сайтов. Будьте внимательны при создании псеводнимов и следуйте рекомендациям поисковых систем по разметке содержимого сайтов и добавлению взаимных ссылок между сайтом на основном домене и его псеводнимом (если псеводним создается как региональная версия основного сайта, то посмотрите, например, рекомендации Google по дополнительной разметке содержимого многоязычных сайтов). Если вы неуверены в необходимости и правильности добавления именно псеводнима, возможно, в вашем случае больше подойдет перенаправление (Redirect: 301 Moved Permanently), которое можно настроить непосредственно в интерфейсе бекенда Вебасиста в приложении «Сайт» в разделе «Структура».

Внутренняя маршрутизация запросов к фронтенду приложения

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

Конфигурация маршрутизации внутри приложения задается в коде самого приложения в файле wa-apps/{APP_ID}/lib/config/routing.php. В нём задаются конкретные правила соответствия между URL запроса и соответствующим модулем/действием.

Например, для приложения Блог файл конфигурации может выглядеть следующим образом:

<?php

return array(
    'blog_tag' => array(
        'url' => 'tag/<tag>',
        'module' => 'post',
        'action' => 'tag'
    ),
    'blog_post' => array(
        'url' => 'post/<id:\d+>',
        'module' => 'post',
    ),
    'rss' => array(
        'url' => 'rss',
        'action' => 'rss'
    )
);

Параметр url в данном случае указывается относительно URL приложения (для данного примера это URL вида http://{ИМЯ_ДОМЕНА}/{ПУТЬ_К_ФРЕЙМВОРКУ}/news/).

Параметры module и action определяют модуль и экшен, которые запускаются для обработки запроса на соответствующий URL. Эти параметры являются опциональными и в случае, если какой-либо из них не указан, то применяется модуль и/или экшен по умолчанию. Название модуля/экшена по умолчанию задается в общесистемном файле wa-config/routing.php (см. выше). Если модуль по умолчанию в общесистемном конфигурационном файле не задан, то название модуля по умолчанию — frontend.

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

Примеры соответствия URL и вызовов методов модулей

Ниже представлено несколько примеров поиска системой методов контроллеров/экшенов, ответственных за обработку запросов (примеры соответствуют приведенному выше файлу конфигурации):

/news/tag/travel

  1. blogPostTagController->execute()
  2. blogPostTagAction->execute()
  3. blogPostActions->tagAction()

/news/post/45

  1. blogPostController->execute()
  2. blogPostAction->execute()
  3. blogPostActions->defaultAction()

/news/rss

  1. blogFrontendRssController->execute()
  2. blogFrontendRssAction->execute()
  3. blogFrontendActions->rssAction()

Система ищет класс и метод в указанной последовательности и запускает первый, который нашла. Подробно правила, по которым система определяет класс, соответствующий паре модуль+экшен, рассматриваются в разделе «Правила и рекомендации по именованию».

Передача параметров в адресе запроса

Правила маршрутизации позволяют передавать через адрес запроса переменные в контроллер.

В приведённом выше примере файла конфигурации в полях url присутствуют конструкции в угловых скобках, например, 'tag/<tag>'; в них указано имя параметра, которому будет присвоено значение, полученное из адреса полученного запроса.

Параметры передаются в переменных окружения и доступны в PHP-коде контроллера с помощью вызова метода системного класса waRequest::param(...). Например, для конфигурации маршрутизации, описанной в примере выше, запрос на URL вида .../blog/tag/cloud запустит выполнение действия tag в модуле post и передаст в действие параметр с именем tag и значением cloud:

// Запрос на .../blog/tag/cloud
$tag = waRequest::param('tag'); // вернет строку 'cloud'

Имя параметра маршрутизации в конфигурации может снабжаться дополнительным индикатором типа переменной в виде префикса i или s (целое число или строка соответственно). Например, правило может быть записано следующим образом: post/<id:\d+>.

// Запрос на .../blog/post/32
$id = waRequest::param('id'); // вернет целое число 32

// Запрос .../blog/post/some-string-here:
// 	правило маршрутизации не сработает,
// 	поскольку some-string-here не удовлетворяет регулярному выражению \d+
// 	(не является положительным числом)

Подробнее о классе waRequest см. раздел «Переменные окружения».