o-log/php-router

There is no license information available for the latest version (2.4) of this package.

PHP router built around classes

2.4 2018-11-04 17:11 UTC

This package is auto-updated.

Last update: 2024-03-29 03:25:34 UTC


README

Вот пример класса экшена, который выводит страницы термов по адресам вида /term/ID и получает идентификатор терма из адреса:

<?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(), который генерирует страницу для конкретных параметров

Класс экшена должен имплементить интерфейс InterfaceAction.

Для того, чтобы вывести ссылку на страницу этого экшена, нужно создать объект экшена (передав конструктору контекст) и вызвать метод url() этого объекта. Например вот ссылка на страницу терма с идентификатором 3:

(new DemoTermAction(3))->url()

Если экшен не использует параметры - можно не писать метод urlMask(), в этом случае метод url() возвращает одновременно и адрес страницы, и маску адреса. Вот пример:

public function url(){
    return '/terms';
}

Возможна ситуация, когда идентификатор объекта отсутствует в адресе в явном виде - например, когда адрес объекта хранится в БД. В таком случае маску адреса возвращать не нужно, а нужно реализовать специальный метод parse():

/**
 * @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.

POST запросы

Метод action вызывает обработчик независимо от метода запроса. Для роутинга только POST запросов можно использовать метод post(). При использовании этого метода если обработчик подходит, но запрос не POST - будет возвращен код 405.

Какие задачи решает роутер

Генерация адресов для экшенов

Для того, чтобы сгенерировать адрес для экшена, нужно собзать объект экшена с параметрами и вызвать для него метод url().

Удобная навигация по коду

Для генерации адреса и для вывода результата используется один и тот же класс. Поэтому, если в коде где-то генерируется адрес для экшена - можно перейти в класс экшена, просто кликнув в IDE на вызов метода url.

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

В коде не должно быть имен классов, имен функций и урлов в виде строковых констант

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

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