Pull to refresh

Быстрый роутинг на PHP

Reading time 3 min
Views 45K
image
Уходя от использования роутинга в .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
Tags:
Hubs:
+5
Comments 48
Comments Comments 48

Articles