В PHP-приложении, таком как XF2, нам нужен способ принять запрос определенного URL-адреса от пользователя, понять, какой контроллер, метод и данные использует этот URL-адрес, чтобы предоставить соответствующий ответ пользователю. Концепция преобразования URL-адреса в местоположение в коде известна как "маршрутизация"(routing).
В XF2 маршрутизация почти полностью управляется из Админ-панели(далее ACP). Найти его можно по пути ACP > Development > Routes
. Маршруты делятся на два типа, Публичный(далее Public) и Админ(далее Admin) они обеспечивают маршрутизацию запросов в приложениях соответственно.
На странице маршрутов (см. выше), найдите маршрут account/
. Это Public маршрут, обеспечивающий маршрутизацию запросов к URL-адресу index.php?account/
. Этот маршрут простой; он состоит из небольшого количества конфигураций. Он состоит из "префикса маршрута"(Route prefix), "контекста раздела"(section context) и класса контроллера(controller class). Давайте разберемся в этом более подробно:
Префикс маршрута идёт после index.php?
и перед первым /
. Это первый шаг в определении контроллера, к которому идёт запрос.
Контекст раздела сообщает навигационным системам в XF, какая вкладка навигации должна быть выбрана, когда посетитель просматривает страницу, по этому маршруту. Для Public
маршрутов контекст раздела должен быть идентификатором вкладки верхнего уровня. Для маршрутов Admin
должен обратиться к идентификатору самой вкладки навигации в ACP(независимо от глубины).
В случае с маршрутом index.php?account/
, контекст раздела не обязателен, поскольку у нас нет вкладки навигации "account". Чтобы увидеть это в действии, просто измените значение "контекст раздела" на "forums", сохраните изменения и перейдите в свою учетную запись index.php?account/
. Теперь вы должны увидеть, что выбрана вкладка навигации "Форумы"!
Это имя класса контроллера, которое должно быть вызвано, когда запрос совпадает с этим маршрутом. В случае с маршрутом "account/", у нас есть XF:Account
. Это загрузит контроллер учетной записи. (Смотрите Короткие имена классов для дополнительной информации). Код этого контроллера располагается по этому пути src/XF/Pub/Controller/Account.php
. Обратите внимание, как короткие имена классов могут преобразовываться в «инфикс», а также в префикс (XF) и суффикс (Account). В этом случае инфикс для этого контроллера (Pub) выводится из типа маршрута учетной записи (public).
Выше мы объяснили, как маршрут сопоставляется с определенным контроллером, но мы еще не знаем, как вызывается определенный метод в этом контроллере. Контроллеры являются классами, которые содержат ряд методов, часть URL после префикса маршрута указывает на метод контроллера. Данный URL index.php?account/account-details
, обращается к классу контроллера XF\Pub\Controller\Account
с именем метода actionAccountDetails()
. Если маршрут ничего не указывает, то вызывается метод actionIndex()
.
Вы можете больше узнать о контроллерах в разделе Основы контроллера.
Давайте посмотрим на маршрут members/
. Этот маршрут простой, также как и маршрут account/
, но у него есть заполненное поле; "формат маршрута"(Route format). Чтобы понять, как это работает, посмотрите на свой профиль. URL этого профиля будет выглядеть примерно так index.php?members/your-name.1
. Обратите внимание на your-name.1
. Это та часть, которую мы пытаемся сопоставить, используя "формат маршрута".
"Формат маршрута" позволяет нам извлекать данные из URL запроса, так мы можем передать данные в действие контроллера, чтобы оно могло загрузить определенную информацию; в этом случае загружается профиль запрошенного пользователя. Это также помогает нам создавать ссылки из передаваемых данных. Вот синтаксис:
:int<user_id,username>/:page
Интересно отметить, что важной частью URL-адреса профиля для поиска профиля является не your-name
, а идентификатор пользователя (1
). Чтобы продемонстрировать это, измените часть URL your-name
на not-your-name
.Вы увидите, что правильный профиль найден, и перенаправление выполнено к правильному URL.
Приведенный выше формат указывает, что это целочисленный параметр. Для построения исходящей ссылки мы извлекаем целое число из ключа user_id
. Если ключ имени пользователя передается в данные, он будет "слагифицирован" и добавлен к целочисленному идентификатору, как вы видите в URL-адресе вашего профиля. Для сопоставления входящего URL-адреса это преобразуется в регулярное выражение, соответствующее целочисленному формату параметра.
:page
это ярлык для генерации части ссылки на странице - 123. В этом случае он ищет страницу в параметрах ссылки. Если он найден, он помещается в URL-адрес, а затем удаляется из параметров. Для входящего парсинга, если он совпадает (он может быть пустым), добавит номер страницы к параметрам, передаваемым в контроллер.
Когда маршрут совпадает с определенным контроллером и методом, любые параметры в URL-адресе обернуты в специальный объект, который мы назвали ParameterBag
. Этот объект специально разработан, чтобы отделить обычные параметры URL с теми, которые прибывают из соответствия маршрута. Объект ParameterBag
передается в каждое действие контроллера и используется следующим образом:
$userId = $params->user_id;
Также можно разделять маршруты на дополнительные суб-имена. Вы можете увидеть это в действии, глядя на маршрут members/following
. В этом примере, following
является суб-именем маршрута members
. Обычно URL-адрес выглядит следующим образом index.php?members/following
, где часть following
будет указывать на действие и просто соответствовать нормальному маршруту members/
. Однако, если есть маршрут, который соответствует префиксу «members» и «sub-name», указанному ниже, он будет использоваться вместо members/following
. Это верно, поэтому он создает ссылку, как показано ниже:
members/:int<user_id,username>/following/:page
Для сопоставления входящего маршрута, этот маршрут будет проверен перед members
; если он совпадает, он будет использоваться.
Эта система суб-имён позволяет изменять поведение, например, изменять положение параметров или подгруппировать маршруты на разных контроллерах или с разными параметрами. Пример последнего можно увидеть в менеджере ресурсов и надстройках Media Gallery.