Роутинг — Часть 1

Комментарии: 56  Просмотры: 50 098

Вот мы и дошли до очень важной темы — темы Роутинга в Кохане. Хочу поблагодарить Семёна c phpforum.ru за разъяснение некоторых нюансов в этой достаточно сложной теме. Теперь можно приступать.
Роутинг — это процесс определения маршрута внутри нашего приложения после поступления запроса. Т.е. после того, как мы переходим по ссылке в адресной строке, происходит ее обработка, согласно определенным правилам. Мы с вами уже немного работали с роутами, когда прописывали свой Контроллер Page вместо Контроллера Welcome. И даже добавляли в него свои методы (кто забыл, смотрите урок Заготовка для блога — Часть1). Таким образом при переходе по ссылке http://kohana у нас вызывался Контроллер Page и метод index, а вот для вызова методов about и contacts нужно было уже писать http://kohana/page/about и http://kohana/page/contacts, т.е. название Контроллера, а потом название метода. Это не очень красиво. Но если написать в адресной строке http://kohana/about, то вместо нашей страницы «О сайте» мы все равно получим главную страницу. Еще надо отметить, что как-то не очень хорошо, когда все страницы лежат в одном Контроллере, тем более такие. Все-таки основная страница — это основная страница. Там будут выводиться статьи и всяческая динамическая информация вроде количества просмотров, количества комментариев и так далее. А страницы «О сайте» и «Контакты» — это статика, обычно их один раз написали и все. Давайте вынесем их в отдельный Контроллер. Для этого в папке с двумя нашими Контроллерами создадим еще один с названием static.php и со следующим кодом (я скопировал его из Контроллера Page, а там удалил):

<?php defined('SYSPATH') or die('No direct script access.');
 
class Controller_Static extends Controller_Common {
 
    // Страница о сайте
    public function action_about()
    {
        $content = View::factory('/pages/about');
        $this->template->content = $content;
    }
 
    // Страница контактов    
    public function action_contacts()
    {
        $content = View::factory('/pages/contacts');
        $this->template->content = $content;
    }	
 
} // End Static

В этом Контроллере пусть у нас будут такие вот статичные страницы (О сайте, Контакты, FAQ, Правила, Друзья итд). В принципе мы уже можем работать с этими страницами. Если доступ к главной странице таким же и остался — через http://kohana или http://kohana/page, то для этих страниц ссылки будут http://kohana/static/about и http://kohana/static/contacts. То есть сменили «шило на мыло». Было page, стало static. Как избавиться от сегмента static ? В этом нам помогут роуты. Для начала давайте рассмотрим структуру роута на примере роута по умолчанию (находится в файле bootstrap.php в самом низу).

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

Здесь мы видим статический метод set, которому передаются два параметра. Первый параметр — это название данного роута. Второй — какое-то правило. На самом деле есть еще третий параметр, который используется по необходимости — это регулярное выражение. С первым параметром все ясно. Второй параметр выглядит у нас так:

(<controller>(/<action>(/<id>)))

Косая черта служит для разделения сегментов адреса друг от друга (в принципе вместо косой черты можно сделать что-то другое, подчеркивание например). Угловые скобки <> указывают, что то, что попадет в них, будет присвоено переменной с именем внутри этих скобок (если этот момент пока непонятен, не волнуйтесь, позже я покажу это на примере). Этих скобок может и не быть, если требуется, чтобы сегмент адреса четко совпадал с роутом (это мы рассмотрим чуть ниже). Круглые скобки означают, что данный параметр необязателен. Т.е. он может быть, а может и не быть. Вы можете сами это проверить. Главная страница будет работать по такому адресу http://kohana/page/index и по такому http://kohana/page и даже по такому http://kohana. Следовательно, чтобы сделать указание Контроллера обязательным, второй параметр нужно изменить на такой:

<controller>(/<action>(/<id>))

Естественно, необходимо соблюдать вложенность скобок. Не может быть, например, необязательный Контроллер, но обязательный Id. Думаю с этим все понятно.
Как Кохана определяет, какой Контроллер вызывать, если мы не указали его в адресной строке, например перешли по адресу http://kohana. Для этого у роута есть функция defaults, в которую передается некий массив параметров в виде ключ — значение, где ключом будет название параметра, а значением, как ни странно, его значение. Нам пока достаточно знать два параметра. Это controller — принимающий название Контроллера, который будет запущен и action — название метода этого Контроллера. Вот мы и написали туда наш Контроллер page и наш метод index, которые собственно и срабатывают. Но вернемся к нашей задачке со статическими страницами. Одним из вариантов ее решения будет два новых роута:

Route::set('about', 'about')
	->defaults(array(
            'controller' => 'static',
            'action'     => 'about',
	)); 
 
Route::set('contacts', 'contacts')
	->defaults(array(
            'controller' => 'static',
            'action'     => 'contacts',
	));

Попробуйте зайти на http://kohana/about или http://kohana/contacts. Все должно работать (не забудьте поправить ссылки в шаблоне). Получается, что когда вы переходите по ссылке http://kohana/about, то сегмент с about попадает под правило первого роута, поэтому вызывается Контроллер static и Метод about. Со второй ссылкой аналогично, только теперь уже срабатывает второй роут.
Обратите внимание, угловые скобки мы не использовали. Т.е. нам нужно именно четкое совпадение или с about, или с contacts. Если все же использовать угловые скобки, то мы все время будем попадать на страницу «О сайте», причем даже при вводе таких адресов как http://kohana/faq так как будет выполняться первый же роут, как соответствующий условию. Просто в параметр about попадет слово «faq», которое потом можно получить например в Базовом Контроллере.
В следующем уроке мы перепишем этот пример с использованием регулярного выражения и обойдемся одним роутом вместо двух, а также создадим еще несколько роутов для понимания (или закрепления) материала из этого урока.

<< Назад | Вперед >> | Обсудить на форуме


К записи оставлено 56 коммент.

Ребят, на забывайте, что в bootstrap.php новое правило надо писать перед дефолтным(дефолтное должно идти последним), у меня из-за этого не работало:)

daymont87: спасибо!

у меня теперь не заходит на главную страницу :(

до того как определил контроллер static.php
у меня когда пишу в адресной строке http://localhost/koh.com/about
базе_урл = /koh.com/ не переводит на главную страницу.. пишет что ошибка ..нет такого файла по запращиваему адресу на сервере..
это значит у меня не работают правила из файла .htaccess? или у всех так? если набирать не существующий адрес например http://kohana/primer у меня выдаст ошибку..не переведет на главную.. выдаст ошибку «HTTP_Exception_404 [ 404 ]: The requested URL primer was not found on this server.» как быть?

цитата — Если все же использовать угловые скобки, то мы все время будем попадать на страницу «О сайте», причем даже при вводе таких адресов как http://kohana/faq так как будет выполняться первый же роут, как соответствующий условию. Просто в параметр about попадет слово «faq», которое потом можно получить например в Базовом Контроллере.

у меня при http://kohana/index.php/faq видает
Kohana_HTTP_Exception [ 404 ]: The requested URL faq was not found on this server.

что я не так сделал? или не так понял?

Наверное не так поняли. Чтобы этот адрес работал нужно сделать под него роут. Мы этого в данной статье не делали.

Здравствуйте! Подскажите, пожалуйста! Можно ли как-то реализовать следующее: при открытии страницы она всегда обрабатывалась бы одним контроллером, но если вызов происходил бы через Request::factory, то вызывался бы контроллер с соответствующим названием. Первую часть реализовать получилось, а вот со второй проблемы :(

в шаблоне views/main.php нужно исправить
<a href="»>О сайте
<a href="»>Мои контакты

на

<a href="»>О сайте
<a href="»>Мои контакты

в шаблоне views/main.php нужно исправить
URL::site(‘pages/about’) и URL::site(‘pages/contacts’);

на

URL::site(‘about’) и URL::site(‘contacts’);

До чего же полезный материал! История, как наверное, у многих-писал сайт с 0, потом когда посмотрел на утро, то что-то не так. Понимал, что сейчас буду писать велосипеды: сел за изучение данного фреймворка. Автору сайта, огромный спасибо, дойдут руки до Donate-обязательно исполню. Без П. ;)

Привет всем! подскажите, может кто сталкивался. при вызове екшена любого контроллера оно добавляет название контроллера ко всем ссылкам на сайте.

Route::set('about', 'about')
	->defaults(array(
            'controller' => 'static',
            'action'     => 'about',
	)); 

Route::set('contacts', 'contacts')
	->defaults(array(
            'controller' => 'static',
            'action'     => 'contacts',
	));

Не работает — всё равно выкидывает на главную страницу

эти роуты следует поместить над дефолтным для главной страницы, и будет ок

Спасибо. Все заработало.



Оставить комментарий или два

Пожалуйста, зарегистрируйтесь для комментирования.