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

Определение маршрутов

Phalcon\Mvc\Router обеспечивает расширенные возможности маршрутизации. В режиме MVC вы можете определить маршруты и сопоставить их с требуемыми контроллерами / действиями. Маршрут определяется следующим образом:

<?php

use Phalcon\Mvc\Router;

// Создание маршрутизатора
$router = new Router();

// Определить маршрут
$router->add(
    '/admin/users/my-profile',
    [
        'controller' => 'users',
        'action'     => 'profile',
    ]
);

// Другой маршрут
$router->add(
    '/admin/users/change-password',
    [
        'controller' => 'users',
        'action'     => 'changePassword',
    ]
);

$router->handle();

Первый параметр метода add() является шаблоном, которому вы хотите соответствовать, и, дополнительно, второй параметр является набором путей. В этом случае, если URI - /admin/users/my-profile, то контроллер users с его профилем действия будет выполнен. Важно помнить, что маршрутизатор не выполняет контроллер и действие, он только собирает эту информацию, чтобы сообщить правильному компоненту (т. е. Phalcon\Mvc\Dispatcher), что это контроллер/действие, которое он должен выполнить.

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

<?php

use Phalcon\Mvc\Router;

// Создание маршрутизатора
$router = new Router();

// Определение маршрута
$router->add(
    '/admin/:controller/a/:action/:params',
    [
        'controller' => 1,
        'action'     => 2,
        'params'     => 3,
    ]
);

В приведенном выше примере мы используем подстановочные знаки, чтобы сделать маршрут действительным для многих URI. Например, при доступе к следующему URL-адресу (/admin/users/a/delete/dave/301):

КонтроллерДействиеПараметрПараметр
users delete dave 301

Метод add() получает шаблон, который может дополнительно иметь предопределенные заполнители и модификаторы регулярных выражений. Все шаблоны маршрутизации должны начинаться с символа косой черты (/). Регулярный синтаксис выражения такое же, как регулярные выражения PCRE. Обратите внимание, что нет необходимости добавлять разделители регулярных выражений. Все шаблоны маршрутов нечувствительны к регистру.

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

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

ЗаполнительРегулярное выражениеИспользование
/:module /([a-zA-Z0-9\_\-]+) Соответствует допустимому имени модуля только буквенно-цифровым символам
/:controller /([a-zA-Z0-9\_\-]+) Соответствует допустимому имени контроллера только буквенно-цифровым символам
/:action /([a-zA-Z0-9_-]+) Соответствует допустимому имени действия только буквенно-цифровым символам
/:params (/.*)* Соответствует списку необязательных слов, разделенных косой чертой. Используйте этот заполнитель только в конце маршрута
/:namespace /([a-zA-Z0-9\_\-]+) Соответствует одноуровневому имени пространства имен
/:int /([0-9]+) Соответствует целочисленному параметру

Имена контроллеров camelized, это означает, что символы ( - ) и ( _ ) удаляются и следующий символ прописными буквами. Например, some_controller преобразуется в SomeController.

Поскольку вы можете добавить много маршрутов по мере необходимости с помощью метода add(), порядок добавления маршрутов указывает их релевантность, добавленные новые маршруты имеют большую актуальность, чем добавлено в первый раз. Внутренне все определенные маршруты пересекаются в обратном порядке, пока Phalcon\Mvc\Router не найдет тот, который соответствует данному URI и обрабатывает его, игнорируя остальные.

Параметры с именами

В приведенном ниже примере показано, как определить имена для параметров маршрута:

<?php

$router->add(
    '/news/([0-9]{4})/([0-9]{2})/([0-9]{2})/:params',
    [
        'controller' => 'posts',
        'action'     => 'show',
        'year'       => 1, // ([0-9]{4})
        'month'      => 2, // ([0-9]{2})
        'day'        => 3, // ([0-9]{2})
        'params'     => 4, // :params
    ]
);

В приведенном выше примере маршрут не определяет часть controller или action.Эти части заменены на фиксированные значения (posts и show). Пользователь не будет знать контроллер, который действительно отправлен по запросу. Внутри контроллера эти именованные параметры можно получить следующим образом:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction()
    {
        // Получить параметр 'year'
        $year = $this->dispatcher->getParam('year');

        // Получить параметр 'month'
        $month = $this->dispatcher->getParam('month');

        // Получить параметр 'day'
        $day = $this->dispatcher->getParam('day');

        // ...
    }
}

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

<?php

$router->add(
    '/documentation/{chapter}/{name}.{type:[a-z]+}',
    [
        'controller' => 'documentation',
        'action'     => 'show',
    ]
);

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

<?php

use Phalcon\Mvc\Controller;

class DocumentationController extends Controller
{
    public function showAction()
    {
        // Получить параметр 'name'
        $name = $this->dispatcher->getParam('name');

        // Получить параметр 'type'
        $type = $this->dispatcher->getParam('type');

        // ...
    }
}

Короткий синтаксис

Если вам не нравится использовать массив для определения путей маршрута, также доступен альтернативный синтаксис. Следующие примеры дают тот же результат:

<?php

// Краткая форма
$router->add(
    '/posts/{year:[0-9]+}/{title:[a-z\-]+}',
    'Posts::show'
);

// Форма массива
$router->add(
    '/posts/([0-9]+)/([a-z\-]+)',
    [
       'controller' => 'posts',
       'action'     => 'show',
       'year'       => 1,
       'title'      => 2,
    ]
);

Смешивание массива и короткого синтаксиса

Массив и короткий синтаксис можно смешать для определения маршрута, в этом случае обратите внимание, что именованные параметры автоматически добавляются к маршрутам маршрута в соответствии с положением, в котором они были определены:

<?php

// Первая позиция должна быть пропущена, потому что
// она используется для именованного параметра 'country'
$router->add(
    '/news/{country:[a-z]{2}}/([a-z+])/([a-z\-+])',
    [
        'section' => 2, // Позиции начинаются с 2
        'article' => 3,
    ]
);

Маршрутизация к модулям

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

<?php

use Phalcon\Mvc\Router;

$router = new Router(false);

$router->add(
    '/:module/:controller/:action/:params',
    [
        'module'     => 1,
        'controller' => 2,
        'action'     => 3,
        'params'     => 4,
    ]
);

В этом случае маршрут всегда должен иметь имя модуля как часть URL-адреса. Например, следующий URL: /admin/users/edit/sonny будет обработан как:

МодульКонтроллерДействиеПараметр
admin users edit sonny

Или можно привязать определенные маршруты к определенным модулям:

<?php

$router->add(
    '/login',
    [
        'module'     => 'backend',
        'controller' => 'login',
        'action'     => 'index',
    ]
);

$router->add(
    '/products/:action',
    [
        'module'     => 'frontend',
        'controller' => 'products',
        'action'     => 1,
    ]
);

Или привязать их к определенным пространствам имен:

<?php

$router->add(
    '/:namespace/login',
    [
        'namespace'  => 1,
        'controller' => 'login',
        'action'     => 'index',
    ]
);

Пространства имен / имена классов должны передаваться отдельно:

<?php

$router->add(
    '/login',
    [
        'namespace'  => 'Backend\Controllers',
        'controller' => 'login',
        'action'     => 'index',
    ]
);

Ограничения метода HTTP

Когда вы добавляете маршрут, используя просто add(), маршрут будет включен для любого метода HTTP. Иногда мы можем ограничить маршрут определенным методом, это особенно полезно при создании приложений RESTful:

<?php

// Этот маршрут будет соответствовать только если метод HTTP GET
$router->addGet(
    '/products/edit/{id}',
    'Products::edit'
);

// Этот маршрут будет соответствовать только если HTTP-метод POST
$router->addPost(
    '/products/save',
    'Products::save'
);

// Этот маршрут будет соответствовать, если HTTP-метод - POST или PUT
$router->add(
    '/products/update',
    'Products::update'
)->via(
    [
        'POST',
        'PUT',
    ]
);

Использование преобразователей

Конвертеры позволяют вам свободно преобразовывать параметры маршрута, прежде чем передавать их диспетчеру. В следующих примерах показано, как их использовать:

<?php

// Название действия позволяет тире, действие может быть: /products/new-ipod-nano-4-generation
$route = $router->add(
    '/products/{slug:[a-z\-]+}',
    [
        'controller' => 'products',
        'action'     => 'show',
    ]
);

$route->convert(
    'slug',
    function ($slug) {
        // Преобразование пути - удаление тире
        return str_replace('-', '', $slug);
    }
);

Другой вариант использования для обратной привязки — привязка модели к маршруту. Это позволяет непосредственно передавать модель в определенное действие:

<?php
 
// В этом примере выполняется предположение, что идентификатор 
// используется в качестве параметра в url: /products/4
$route = $router->add(
    '/products/{id}',
    [
        'controller' => 'products',
        'action'     => 'show',
    ]
);
 
$route->convert(
    'id',
    function ($id) {
        // Fetch the model
        return Product::findFirstById($id);
    }
);

Группы маршрутов

Если набор маршрутов имеет общие пути, они могут быть сгруппированы, чтобы легко поддерживать их:

<?php
 
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Router\Group as RouterGroup;
 
$router = new Router();
 
// Создание группы с общим модулем и контроллером
$blog = new RouterGroup(
    [
        'module'     => 'blog',
        'controller' => 'index',
    ]
);
 
// Все маршруты начинаются с /blog
$blog->setPrefix('/blog');
 
// Добавление маршрута в группу
$blog->add(
    '/save',
    [
        'action' => 'save',
    ]
);
 
// Добавить еще один маршрут к группе
$blog->add(
    '/edit/{id}',
    [
        'action' => 'edit',
    ]
);
 
// Этот маршрут соответствует контроллеру, 
// отличному от используемого по умолчанию
$blog->add(
    '/blog',
    [
        'controller' => 'blog',
        'action'     => 'index',
    ]
);
 
// Добавление группы к маршрутизатору
$router->mount($blog);

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

<?php
 
use Phalcon\Mvc\Router\Group as RouterGroup;
 
class BlogRoutes extends RouterGroup
{
    public function initialize()
    {
        // Пути по умолчанию
        $this->setPaths(
            [
                'module'    => 'blog',
                'namespace' => 'Blog\Controllers',
            ]
        );
 
        // Все маршруты начинаются с /blog
        $this->setPrefix('/blog');
 
        // Добавление маршрута в группу
        $this->add(
            '/save',
            [
                'action' => 'save',
            ]
        );
 
        // Добавить еще один маршрут к группе
        $this->add(
            '/edit/{id}',
            [
                'action' => 'edit',
            ]
        );
 
        // Этот маршрут соответствует контроллеру, 
        // отличному от используемого по умолчанию
        $this->add(
            '/blog',
            [
                'controller' => 'blog',
                'action'     => 'index',
            ]
        );
    }
}

Затем подключите группу в маршрутизаторе:

<?php

// Добавление группы к маршрутизатору
$router->mount(
    new BlogRoutes()
);

Соответствие Маршрутов

Действительный URI должен быть передан маршрутизатору, чтобы он мог обработать его и найти соответствующий маршрут. По умолчанию URI маршрутизации берется из переменной $_GET['_url'], созданной модулем механизма перезаписи. Несколько правил перезаписи, которые очень хорошо работают с Phalcon:

RewriteEngine On
RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
RewriteRule   ^((?s).*)$ index.php?_url=/$1 [QSA,L]

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

<?php

use Phalcon\Mvc\Router;

// Создание маршрутизатора
$router = new Router();

// Определите маршруты здесь, если таковые имеются
// ...

// Принимая URI из $_GET['_url']
$router->handle();

// Или установка значения URI напрямую
$router->handle('/employees/edit/17');

// Получение обработанного контроллера
echo $router->getControllerName();

// Получение обработанного действия
echo $router->getActionName();

// Получение согласованного маршрута
$route = $router->getMatchedRoute();

Именование Маршрутов

Каждый маршрут, добавляемый к маршрутизатору, хранится внутри как объект Phalcon\Mvc\Router\Route. Этот класс инкапсулирует все детали каждого маршрута. Например, мы можем дать имя пути, чтобы однозначно идентифицировать его в нашем приложении. Это особенно полезно, если вы хотите создать URL-адреса из него.

<?php

$route = $router->add(
    '/posts/{year}/{title}',
    'Posts::show'
);

$route->setName('show-posts');

Затем, используя, например, компонент Phalcon\Mvc\Url, мы можем строить маршруты от его имени:

<?php

// Возвращает /posts/2012/phalcon-1-0-released
echo $url->get(
    [
        'for'   => 'show-posts',
        'year'  => '2012',
        'title' => 'phalcon-1-0-released',
    ]
);

Примеры использования

Ниже приведены примеры пользовательских маршрутов:

<?php

// Соответствует '/system/admin/a/edit/7001'
$router->add(
    '/system/:controller/a/:action/:params',
    [
        'controller' => 1,
        'action'     => 2,
        'params'     => 3,
    ]
);

// Соответствует '/es/news'
$router->add(
    '/([a-z]{2})/:controller',
    [
        'controller' => 2,
        'action'     => 'index',
        'language'   => 1,
    ]
);

// Соответствует '/es/news'
$router->add(
    '/{language:[a-z]{2}}/:controller',
    [
        'controller' => 2,
        'action'     => 'index',
    ]
);

// Соответствует '/admin/posts/edit/100'
$router->add(
    '/admin/:controller/:action/:int',
    [
        'controller' => 1,
        'action'     => 2,
        'id'         => 3,
    ]
);

// Соответствует '/posts/2015/02/some-cool-content'
$router->add(
    '/posts/([0-9]{4})/([0-9]{2})/([a-z\-]+)',
    [
        'controller' => 'posts',
        'action'     => 'show',
        'year'       => 1,
        'month'      => 2,
        'title'      => 3,
    ]
);

// Соответствует '/manual/en/translate.adapter.html'
$router->add(
    '/manual/([a-z]{2})/([a-z\.]+)\.html',
    [
        'controller' => 'manual',
        'action'     => 'show',
        'language'   => 1,
        'file'       => 2,
    ]
);

// Соответствует /feed/fr/le-robots-hot-news.atom
$router->add(
    '/feed/{lang:[a-z]+}/{blog:[a-z\-]+}\.{type:[a-z\-]+}',
    'Feed::get'
);

// Соответствует /api/v1/users/peter.json
$router->add(
    '/api/(v1|v2)/{method:[a-z]+}/{param:[a-z]+}\.(json|xml)',
    [
        'controller' => 'api',
        'version'    => 1,
        'format'     => 4,
    ]
);

Поведение по умолчанию

Phalcon\Mvc\Router имеет поведение по умолчанию, которое обеспечивает очень простую маршрутизацию, которая всегда ожидает URI, который соответствует следующему шаблону:  /:controller/:action/:params

Например, для URL-адреса, подобного этому http://phalconphp.com/documentation/show/about.html, этот маршрутизатор переведет его следующим образом:

КонтроллерДействиеПараметр
documentation show about.html

Если вы не хотите, чтобы маршрутизатор имел это поведение, вы должны создать маршрутизатор, передающий false как первый параметр:

<?php

use Phalcon\Mvc\Router;

// Создание маршрутизатора без маршрутов по умолчанию
$router = new Router(false);

Настройка маршрута по умолчанию

Когда ваше приложение доступно без какого-либо маршрута, маршрут «/» используется для определения того, какие пути должны использоваться для показа начальной страницы вашего веб-сайта / приложения:

<?php

$router->add(
    '/',
    [
        'controller' => 'index',
        'action'     => 'index',
    ]
);

Не найденные пути

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

<?php

// Установить 404 пути
$router->notFound(
    [
        'controller' => 'index',
        'action'     => 'route404',
    ]
);

Обычно это для страницы с ошибкой 404.

Это будет работать, только если маршрутизатор был создан без маршрутов по умолчанию: $router = Phalcon\Mvc\Router(FALSE);

Настройка путей по умолчанию

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

<?php

// Установка определенного значения по умолчанию
$router->setDefaultModule('backend');
$router->setDefaultNamespace('Backend\Controllers');
$router->setDefaultController('index');
$router->setDefaultAction('index');

// Использование массива
$router->setDefaults(
    [
        'controller' => 'index',
        'action'     => 'index',
    ]
);

Работа с дополнительными/замыкающими слэшами

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

<?php

use Phalcon\Mvc\Router;

$router = new Router();

// Автоматически удалять завершающие косые черты
$router->removeExtraSlashes(true);

Или можно изменить определенные маршруты, чтобы дополнительно принимать конечные косые черты:

<?php

// [/] {0,1} позволяет этому маршруту дополнительно иметь косую черту
$router->add(
    '/{language:[a-z]{2}}/:controller[/]{0,1}',
    [
        'controller' => 2,
        'action'     => 'index',
    ]
);

Сопоставление обратных вызовов

Иногда маршруты следует сопоставлять только в том случае, если они отвечают определенным условиям. Вы можете добавить произвольные условия для маршрутов, используя обратный вызов beforeMatch(). Если эта функция возвращает false, маршрут будет считаться несогласованным:

<?php

$route = $router->add('/login',
    [
        'module'     => 'admin',
        'controller' => 'session',
    ]
);

$route->beforeMatch(
    function ($uri, $route) {
        // Проверить, был ли запрос выполнен с помощью Ajax
        if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
            return false;
        }

        return true;
    }
);

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

<?php

class AjaxFilter
{
    public function check()
    {
        return $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
    }
}

И используйте этот класс вместо анонимной функции:

<?php

$route = $router->add(
    '/get/info/{id}',
    [
        'controller' => 'products',
        'action'     => 'info',
    ]
);

$route->beforeMatch(
    [
        new AjaxFilter(),
        'check'
    ]
);

Что касается Phalcon 3, есть еще один способ проверить это:

<?php

$route = $router->add(
    '/login',
    [
        'module'     => 'admin',
        'controller' => 'session',
    ]
);

$route->beforeMatch(
    function ($uri, $route) {
        /**
         * @var string $uri
         * @var \Phalcon\Mvc\Router\Route $route
         * @var \Phalcon\DiInterface $this
         * @var \Phalcon\Http\Request $request
         */
        $request = $this->getShared('request');

        // Проверить, был ли запрос выполнен с помощью Ajax
        return $request->isAjax();
    }
);

Ограничения имени хоста

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

<?php

$route = $router->add(
    '/login',
    [
        'module'     => 'admin',
        'controller' => 'session',
        'action'     => 'login',
    ]
);

$route->setHostName('admin.company.com');

Имя хоста также может быть передано в виде регулярных выражений:

<?php

$route = $router->add(
    '/login',
    [
        'module'     => 'admin',
        'controller' => 'session',
        'action'     => 'login',
    ]
);

    $route->setHostName('([a-z]+).company.com');

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

<?php

use Phalcon\Mvc\Router\Group as RouterGroup;

// Создайте группу с общим модулем и контроллером
$blog = new RouterGroup(
    [
        'module'     => 'blog',
        'controller' => 'posts',
    ]
);

// Ограничение имени хоста
$blog->setHostName('blog.mycompany.com');

// Все маршруты начинаются с /blog
$blog->setPrefix('/blog');

// По умолчанию маршрут
$blog->add(
    '/',
    [
        'action' => 'index',
    ]
);

// Добавить маршрут в группу
$blog->add(
    '/save',
    [
        'action' => 'save',
    ]
);

// Добавить другой маршрут в группу
$blog->add(
    '/edit/{id}',
    [
        'action' => 'edit',
    ]
);

// Добавить группу в маршрутизатор
$router->mount($blog);

Источники URI

По умолчанию информация URI получена из переменной $ _GET ['_ url'], это передается Rewrite-Engine в Phalcon, вы также можете использовать $ _SERVER ['REQUEST_URI'], если это необходимо:

<?php

use Phalcon\Mvc\Router;

// ...

// Использовать $_GET['_ url'] (по умолчанию)
$router->setUriSource(
    Router::URI_SOURCE_GET_URL
);

// Использовать $_SERVER['REQUEST_URI']
$router->setUriSource(
    Router::URI_SOURCE_SERVER_REQUEST_URI
);

Или вы можете вручную передать URI методу handle():

<?php

$router->handle('/some/route/to/handle');

Тестирование ваших маршрутов

Поскольку этот компонент не имеет зависимостей, вы можете создать файл, как показано ниже, для проверки ваших маршрутов:

<?php

use Phalcon\Mvc\Router;

// Эти маршруты имитируют реальные URI
$testRoutes = [
    '/',
    '/index',
    '/index/index',
    '/index/test',
    '/products',
    '/products/index/',
    '/products/show/101',
];

$router = new Router();

// Добавьте сюда свои пользовательские маршруты
// ...

// Тестирование каждого маршрута
foreach ($testRoutes as $testRoute) {
    // Обрабатывать маршрут
    $router->handle($testRoute);

    echo 'Тестирование ', $testRoute, '<br>';

    // Проверить соответствие одного маршрута
    if ($router->wasMatched()) {
        echo 'Controller: ', $router->getControllerName(), '<br>';
        echo 'Action: ', $router->getActionName(), '<br>';
    } else {
        echo "Tмаршрут не был согласован ни одним маршрутом<br>";
    }

    echo '<br>';
}

События

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

СобытиеОписание
router:beforeCheckRoutes Вызывается перед проверкой всех загруженных маршрутов
router:beforeCheckRoute Вызывается перед проверкой маршрута
router:matchedRoute Вызывается, когда маршрут сопоставляется
router:notMatchedRoute Вызывается любой маршрут.
router:afterCheckRoutes мпосле проверки всех маршрутов
router:beforeMount Вызывается перед тем, как установить новый маршрут

Аннотации Маршрутизатора

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

<?php
 
use Phalcon\Mvc\Router\Annotations as RouterAnnotations;
 
$di['router'] = function () {
    // Использовать маршрутизатор аннотаций. Мы передаем false, 
    // поскольку мы не хотим, чтобы маршрутизатор добавлял свои шаблоны по умолчанию
    $router = new RouterAnnotations(false);
 
    // Прочитайте аннотации из ProductsController, 
    // если URI начинается с /api/products
    $router->addResource('Products', '/api/products');
 
    return $router;
};

Аннотации можно определить следующим образом:

<?php

/**
 * @RoutePrefix('/api/products')
 */
class ProductsController
{
    /**
     * @Get(
     *     '/'
     * )
     */
    public function indexAction()
    {

    }

    /**
     * @Get(
     *     '/edit/{id:[0-9]+}',
     *     name='edit-robot'
     * )
     */
    public function editAction($id)
    {

    }

    /**
     * @Route(
     *     '/save',
     *     methods={'POST', 'PUT'},
     *     name='save-robot'
     * )
     */
    public function saveAction()
    {

    }

    /**
     * @Route(
     *     '/delete/{id:[0-9]+}',
     *     methods='DELETE',
     *     conversors={
     *         id='MyConversors::checkId'
     *     }
     * )
     */
    public function deleteAction($id)
    {

    }

    public function infoAction($id)
    {

    }
}

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

ИмяОписаниеИспользование
RoutePrefix Префикс, добавляемый к каждому URI маршрута. Эта аннотация должна быть помещена в docblock класса @RoutePrefix('/api/products')
Route Эта аннотация отмечает метод как маршрут. Эта аннотация должна быть помещена в docblock метода @Route('/api/products/show')
Get Эта аннотация отмечает метод как маршрут, ограничивающий HTTP метод   GET @Get('/api/products/search')
Post Эта аннотация отмечает метод как маршрут, ограничивающий HTTP метод  POST @Post('/api/products/save')
Put Эта аннотация отмечает метод как маршрут, ограничивающий HTTP метод  PUT @Put('/api/products/save')
Delete Эта аннотация отмечает метод как маршрут, ограничивающий HTTP метод  DELETE @Delete('/api/products/delete/{id}')
Options Эта аннотация отмечает метод как маршрут, ограничивающий HTTP метод OPTIONS @Option('/api/products/info')

Для примечаний, добавляющих маршруты, поддерживаются следующие параметры:

ИмяОписаниеИспользование
methods Определить один или несколько методов HTTP, которым должен соответствовать маршрут @Route('/api/products', methods={'GET', 'POST'})
name Определение имени маршрута @Route('/api/products', name='get-products')
paths Массив путей, таких как тот, который был передан Phalcon\Mvc\Router::add() @Route('/posts/{id}/{slug}', paths={module='backend'})
conversors Хеш конверторов, применяемых к параметрам @Route('/posts/{id}/{slug}', conversors={id='MyConversor::getId'})

Если вы используете модули в своем приложении, лучше использовать метод addModuleResource():

<?php
 
use Phalcon\Mvc\Router\Annotations as RouterAnnotations;
 
$di['router'] = function () {
    // Использование аннотаций маршрутизатора
    $router = new RouterAnnotations(false);
 
    // Прочитать аннотации из Backend\Controllers\ProductsController, 
    // если URI начинается с /api/products
    $router->addModuleResource('backend', 'Products', '/api/products');
 
    return $router;
};

Регистрация экземпляра маршрутизатора

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

Вам нужно добавить код ниже в ваш bootstrap файл (например index.php или app/config/services.php, если вы используете инструменты разработчика Phalcon.

<?php

/**
 * Add routing capabilities
 */
$di->set(
    'router',
    function () {
        require __DIR__ . '/../app/config/routes.php';

        return $router;
    }
);

Вам нужно создать app/config/routes.php и добавить код инициализации маршрутизатора, например:

<?php

use Phalcon\Mvc\Router;

$router = new Router();

$router->add(
    '/login',
    [
        'controller' => 'login',
        'action'     => 'index',
    ]
);

$router->add(
    '/products/:action',
    [
        'controller' => 'products',
        'action'     => 1,
    ]
);

return $router;

Реализация собственного маршрутизатора

Интерфейс Phalcon\Mvc\RouterInterface должен быть реализован для создания собственного маршрутизатора, который заменяет тот, который предоставляется Phalcon.