Пример использования
Вот пример класса экшена, который выводит страницы термов по адресам вида /term/ID и получает идентификатор терма из адреса:, (*1)
<?php
namespace PHPRouterDemo;
use OLOG\InterfaceAction;
class DemoTermAction implements InterfaceAction
{
protected $term_id;
public function __construct($term_id)
{
$this->term_id = $term_id;
}
static public function urlMask()
{
return '/term/(\d+)';
}
public function url(){
return '/term/' . $this->term_id;
}
public function action(){
echo '<div>TERM ' . $this->term_id . '</div>';
}
}
Здесь есть:
- конструктор, который принимает контекст экшена (идентификатор объекта, который надо вывести на страницу)
- метод urlMask(), который возвращает маску адреса для роутинга: регулярное выражение, которому должен соответствовать запрошенный адрес и которое извлекает из адреса параметры экшена
- метод url(), который возвращает адрес страницы этого экшена для конкретных параметров
- метод action(), который генерирует страницу для конкретных параметров, (*2)
Класс экшена должен имплементить интерфейс InterfaceAction., (*3)
Для того, чтобы вывести ссылку на страницу этого экшена, нужно создать объект экшена (передав конструктору контекст) и вызвать метод url() этого объекта. Например вот ссылка на страницу терма с идентификатором 3:, (*4)
(new DemoTermAction(3))->url()
Если экшен не использует параметры - можно не писать метод urlMask(), в этом случае метод url() возвращает одновременно и адрес страницы, и маску адреса. Вот пример:, (*5)
public function url(){
return '/terms';
}
Возможна ситуация, когда идентификатор объекта отсутствует в адресе в явном виде - например, когда адрес объекта хранится в БД. В таком случае маску адреса возвращать не нужно, а нужно реализовать специальный метод parse():, (*6)
/**
* @param $requested_url
* @return null|RubricFeedPageAction
*/
static public function parse($requested_url){
$matches_arr = array();
if (!preg_match('@^(.+)$@', $requested_url, $matches_arr)) {
return null;
}
$term_id = Term::getIdForUrl($matches_arr[1]);
if (!$term_id) {
return null;
}
$name = self::class;
return new DemoTermAction($term_id);
}
Такой метод принимает запрошенный адрес и может вернуть или null (если экшен не умеет обрабатывать этот адрес) или объект экшена, которому уже переданы параметры.
Также класс экшена должен имплементить интерфейс ParseActionInterface., (*7)
POST запросы
Метод action вызывает обработчик независимо от метода запроса. Для роутинга только POST запросов можно использовать метод post(). При использовании этого метода если обработчик подходит, но запрос не POST - будет возвращен код 405., (*8)
Какие задачи решает роутер
Генерация адресов для экшенов
Для того, чтобы сгенерировать адрес для экшена, нужно собзать объект экшена с параметрами и вызвать для него метод url()., (*9)
Удобная навигация по коду
Для генерации адреса и для вывода результата используется один и тот же класс. Поэтому, если в коде где-то генерируется адрес для экшена - можно перейти в класс экшена, просто кликнув в IDE на вызов метода url., (*10)
Можно найти все точки в коде, где используется адрес экшена, просто найдя вызовы метода url., (*11)
В коде не должно быть имен классов, имен функций и урлов в виде строковых констант
Адреса для экшенов хранятся в коде только в одном месте: в самом экшене. Во всех остальных местах для получения адреса можно использовать вызов метода url объекта экшена, таким образом адреса можно менять централизованно., (*12)
Имя класса экшена для роутинга передается роутеру не как строка, а через зарезервированную константу class. Таким образом можно рефакторить классы экшенов, например, переименовывать их, без необходимости находить и менять строки в коде. Также можно находить все использования классов средствами IDE., (*13)