Route (Роутинг)

Роутинг — процесс преобразования URI в набор понятных фреймворку параметров, таких как название контроллера, действия и т.д. Другими словами можно сказать, что роутинг принимает на вход строку URI-адреса, а на выход отдает массив параметров. В Kohana роутинг используется для того, чтобы определить обращению нужный для запуска контроллер и набор параметров для него. В преобразовании принимает участие именно URI-адрес (не путать с URL), в данном случае это часть URL-адреса без хоста и GET-параметров. Например, для адреса http://somehost/file/download/3/?from=index&param2=somevalue URI-адресом будет строка /file/download/3.

Роутинг происходит с помощью роутов, отдельных правил для URI-адреса. При запуске роутинга, каждый роут по порядку проверяет свое правило с URI-адресом, при успешном совпадении роутинг прекращается и роут извлекает параметры из адреса.

В Kohana роутинг происходит в основном с помощью регулярных выражений, поэтому ожидается, что вы имеете некоторый опыт в работе с ними. Настройка роутов по умолчанию происходит в файле bootstrap, но нередко их выносят в отдельный файл для удобства.

Создание роута

Для создания роута существует метод Route::set($name, $uri_callback, $regex), где $name — уникальное имя роута, $uri_callback — правило и $regex — необязательный массив правил регулярных выражений для параметров.

Правило $uri_callback может быть установлено одним из нескольких форматов:

Рассмотрим сначала внутренний формат правил. Он представляет из себя строку, с которой идет проверка на совпадение с заданным URI:

Route::set('news', 'news/view/all');

В данном случае, этому простому правилу будет соотвествовать только один URI news/view/all.

Но гораздо чаще нам приходится обрабатывать более сложные адреса вида news/view/46, post/16-some-post-title.html, support/ticket/5/set/status/closed и т.д.

Для этого в правиле можно указать параметр, который может принимать любое значение в секторе, ограниченном слешами /. Параметр имеет вид <имя параметра>:

Route::set('news_id', 'news/view/<id>');

Этому правилу уже будет подходить большее количество URI, такие как news/view/4, news/view/somestring, news/view/all и т.д. Обратите внимание, что строки news/view и news/view/4/somevalue подходить не будут.

Приведем еще несколько примеров:

Route::set('post', 'post/<id>-<name>.html');
Route::set('support_ticketstatus', 'support/ticket/<id>/set/status/<status>');

Также, можно указать необязательность той или иной части правила, это происходит в виде (произвольное выражение), например:

Route::set('post', 'post(/<id>)');

Данному выражению будут соответствовать адреса post, post/3, post/foobar и т.д.

Необязательность выражения можно вкладывать друг в друга:

Route::set('post', 'post(/read(/<id>))');

Данному правилу соответствуют строки post, post/read, post/read/100 и т.д.

Приведем еще пример:

Route::set('post', 'post(/<action>/<id>(-<name>).html)');

Для этого примера подойдут строки post/read/4-test.html, post, post/read/4.html, post/delete/something.html, post/delete/foo-bar.html и т.д.

Теперь рассмотрим лямбда-функции. Функция должна принимать в качестве единственного аргумента URI и отдавать массив параметров, если проверка прошла и FALSE в противном случае.

Route::set('custom_route', function($url) {
	if(in_array('uri', array('post', 'category', 'tag'))) {
		return array(
			'controller' => $uri,
			'action' => 'index',
		);
	}
	return FALSE;
});

Советуется использовать лямбда-функции для правил только тогда, когда составить их по другому невозможно.

Параметры, полученные при успешном совпадении URI с правилом передаются далее в обращение (Request) и в любой момент доступны из контроллера.

Однако, некоторые параметры являются служебными и нужны для определения запускаемого контроллера:

  • controller — название контроллера, которого запустит обращение.
  • action — название выбранного действия, которое будет запущено обращением в контроллере.
  • directory — директория, в которой должен производиться поиск контроллера.

Параметры по умолчанию

После создания роута, можно указать параметры для него по умолчанию, которые будут возвращены, если не будут найдены в правиле. Для этого существует метод defaults($defaults), где $defaults — массив, индексами которого выступают названия параметров, а элементами — их значения по умолчанию. Вместе с методом Route::set можно строить следующие конструкции:

Route::set('post', 'blog/<controller>(/<action>)/<id>')
	->defaults(array(
		'directory'  => 'blog',
		'action'     => 'read',
	));

После запуска адреса blog/post/4 запустится контроллер Blog_Post, действие index с параметром id равному 4. При запуске же blog/category/delete/all, запустится контроллер Blog_Category, действие delete с параметром id равным all.

При использовании параметров по умолчанию удобно делать роут для главной страницы:

Route::set('default')
	->defaults(array(
		'controller'  => 'default',
		'action'     => 'index',
	));

Теперь, при запуске главной страницы приложения, запустится контроллер Default с действием index.

Обратный роутинг

Обратный роутинг, о чем может понять из названия, выполняет преобразование набора параметров в URL-адрес. Kohana реализует эту функцию через метод Route::url($name, $params, $protocol), где $name — имя роута, $params — массив параметров и необязательный аргумент $protocol — протокол возвращаемого URL.

Приведем пример обратного роутинга:

Route::set('default', '(<controller>(/<action>(/<id>)))')
	->defaults(array(
		'controller' => 'welcome',
		'action'     => 'index',
	));
echo Route::url('default', array(
	'controller' => 'post',
	'action' => 'view',
	'id' => 4,
));

Результатом будет строка /post/view/4.

Кеширование роутов

Мы можем повысить производительность приложения, если будем кешировать роуты, вместо того чтобы устанавливать их при каждом запуске по новой. Делается это через метод Route::cache следующей конструкцией:

if( ! Route::cache())
{
	Route::set('default')
	->defaults(array(
		'controller'  => 'default',
		'action'     => 'index',
	));
	// установка всех дальнейших роутов
	Route::cache(TRUE);
}

Kohana позволяет использовать только обычный (файловый) кеш для кеширования роутов, так что, если вы хотите использовать другую систему, вам придется реализовать это самостоятельно.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *