
Уходя от использования роутинга в .htaccess файле, в первую очередь пришёл к стандартному направлению на index.php: разбирал там URL и вызывал соответствующие контроллеры — долгое время был доволен такой техникой. Однако совсем недавно осознал, что что-то делаю не так, что можно сделать эффективнее и лучше.
Далее я расскажу о своём роутинге, использующем XML для хранения правил и в последующем использующем его сериализованный вид.
Уходя от проверки в индексном файле, хотел в первую очередь избавиться от подобной конструкции
if ($url[1] == 'news'){}
Мне не очень хотелось использовать конструкции, предлагаемые большинством фреймворков, в целом выглядящие в таком виде:
$route->addRule( '/news/{id}/', array( 'controler' = 'news', 'action' = 'showOne' ) );
Изначально хотелось хранить правила роутинга в JSON или XML.
Однако парсить каждый раз файл не очень хорошая идея, и такой тип более пригоден для статической навигации или навигации вида /controller/action/.
Мне же хотелось большей гибкости в настройке роутинга и в конечном итоге решил использовать XML для хранения правил, а после парсинга файла и создания массива правил сериализовывать его в файл (в дальнейшем используя его для получения настроек)
XML-файл правил роутинга выглядит примерно так:
<root> <routes> <route match="exit" controller="user" action="exit" /> <route match="secret" controller="error" action="404"> <route match="love" controller="secret" action="love" /> </route> <route match="user" controller="user" action="list"> <route controller="user" action="user" match="{login}"> <route match="comments" controller="user" action="comments" /> <route match="wall" controller="user" action="wall" /> </route> </route> </routes> </root>
Структура правила представляет собой следующее
XML-элемент правил содержится в элементе /root/routes, элемент правил должен содержать в себе следующие атрибуты:
match — Используется для поиска по URL
controller — Вызываемый контроллер
action — Вызываемый метод
match может содержать как статические данные, например «secret», так и динамические «page-{page|num}», динамические отличаются от статических наличием фигурных скобок и названием переменной в ней (название переменной и её значение будут получены в случае совпадения)
В переменной можно указать её тип:
{param1|num} — выдаст совпадение только в случае, если param1 является числовым значением
{param2|str} — выдаст совпадение только в случае, если param2 содержит в себе только буквы и цифры
На основе XML формируется массив, который разделает статические и динамические правила.
Все потомки так же разделяются на статических и динамических.
Так же в элементе /root/system
хранятся следующие данные:
<route match="index" controller="index" action="index" /> <route match="not_found" controller="error" action="404" />
Соответственно в случае, если совпадения по правилам роутинга найдены не будут, вернётся 404 ошибка, в случае пустого урл — его index значение
Использование выглядит так:
$result = $router->get('/secret/love/');
Результат будет таким:
Array ( [controller] => secret [action] => love [values] => Array ( ) )
$result = $router->get('/user/Testik/wall/');
Array ( [controller] => user [action] => wall [values] => Array ( [login] => Testik ) )
Исходники на BitBucket
Скачать zip gz bz2