Роутинг в PHP на основе аннотаций
В данном скрипте я Вам покажу как из аннотаций можно получать настройки для системы маршрутизации в Вашем проекте. Преимущество настройки маршрутизации на основе PHP аннотаций заключается в том, что Вам не нужно больше создавать дополнительные файлы в которых будут прописываться конфигурации. Все конфигурации находятся прямо перед методом, избавляя нас от необходимости искать их где-то еще. В общем, много говорить не буду, а просто оставлю здесь код. Кстати, в данном примере используется компонент doctrine/annotations, который и ответственен за всю логику парсинга аннотаций.
Сначала создаем файл composer.json:
{
"require": {
"doctrine/annotations": "*"
}
}
Далее в этой же папке выполняем команду
composer install
Создаем файл index.php, первые строки которого выглядят так:
<?php
// подключаем автозагрузчик Composer'a
require_once 'vendor/autoload.php';
Далее в этом же файле создаем класс аннотации @Route:
/**
* Аннотация \@Route представлена классом Route (маршрут)
* Данная аннотация хранит настройки маршрутизации
*
*
* @Annotation - обозначение аннотации
* @Target({"CLASS","METHOD"}) - аннотация может применяться только к классам и методам классов
*/
class Route
{
public $url; // url маршрута
public $handler; // обработчик - метод класса
public $methods;
}
Далее добавляем тестовый контроллер:
// пример контроллера
// у каждого метода аннотация \@Route
// содержит параметры
// в виде ключ => значение, где ключ - это свойство класса,
// а значение - сторока в кавычках, число, или массив
class PageController
{
/**
* @Route(
* url = "/",
* handler = "PageController::index",
* methods = {"GET"}
* )
*/
public function index() {
print __METHOD__;
}
/**
* @Route(
* url = "/login",
* handler = "PageController::login",
* methods = {"GET"}
* )
*/
public function login() {
print __METHOD__;
}
/**
* @Route(
* url = "/article/{id:\d+}",
* handler = "PageController::article",
* methods = {"GET"}
* )
*/
public function article($id) {
print __METHOD__;
}
public function stub() {
print __METHOD__;
}
}
Класс RouteCollector
// класс собирает все маршруты в массив
class RouteCollector
{
// метод получает на вход строковое имя класса
// который содержит роуты
public function collect($class)
{
// объект класса AnnotationReader из пакета doctrine/annotation
$reader = new Doctrine\Common\Annotations\AnnotationReader();
// загружаем класс в объект ReflectionClass
$refClass = new ReflectionClass($class);
// получаем из класса все публичные методы
$refMethods = $refClass -> getMethods(ReflectionMethod::IS_PUBLIC);
// массив полученных объектов Route, описывающих маршрут
$routes = [];
foreach($refMethods as $method)
{
// получаем аннотацию Route
$annotation = $reader -> getMethodAnnotation($method,Route::class);
// если есть аннотация
if($annotation)
$routes[] = $annotation;
}
return $routes;
}
}
Вызываем все это дело так:
// создаем класс коллектора
$collector = new RouteCollector();
// собираем маршруты с класса
$routes = $collector -> collect(PageController::class);
// выводим маршруты
print_r($routes);
Результат примерно следующий:
Array
(
[0] => Route Object
(
[url] => /
[handler] => PageController::index
[methods] => Array
(
[0] => GET
)
)
[1] => Route Object
(
[url] => /login
[handler] => PageController::login
[methods] => Array
(
[0] => GET
)
)
[2] => Route Object
(
[url] => /article/{id:\d+}
[handler] => PageController::article
[methods] => Array
(
[0] => GET
)
)
)
Вот так можно организовать конфигурацию маршрутов в PHP с помощью аннотаций.
-
- Михаил Русаков
Комментарии (4):
у вас опечатка - исправьте в "Сначала создаем файл" comoser.json - на composer.json
Ответить
Исправлено.
Ответить
Скажите пожалуйста, а зачем этот метод лучше следующего метода: route.php Хранит в себе все типы контента( статья, категория, меню сайта и т д) + условия подключения разных шаблонизаторов вывода контента. url.xml - список урл + id элементов с базы данных. route.php - вызывается в главном index php. Универсальный способ сортировать ссылки + не нужно костыли создавать, для обхода ограничений роутинга по шаблонному классу аннотаций.
Ответить
Покажите, пожалуйста, Ваш пример кода, с Github, например, так трудно представить, что имеется ввиду. А код в статье - это, один из вариантов роутинга, из фреймворка Symfony.
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.