Роуты в kohana
Доброго времени суток. Ну вот мы и подошли к изучению роутов в Kohana. Роуты в Kohana — это своего рода маршрутизация запросов. Или другими словами это набор правил по обработке поступивших запросов. Данная тема очень важна. Поэтому отнеситесь к ней с вниманием. Так в предыдущих статьях мы с Вами создали свой контроллер. И если Вы внимательно читали, то я в статье “Принцип работы Kohana (практика)” в качестве примера обьявил класс
Class Controller_Example_Hello extends Controller
где файл с описанием лежит в ./application/classes/controller/example, а заетем идет файл hello.php. И если мы попытаемся перейти по адресу http://books/example/hello, то мы увидим ошибку. Потому, что Kohana не поймет, что в запросе example — это подпапка, в которой находиться контроллер. Вот, для того чтобы Kohana правильно выполнила данный запрос и нужны роуты.
Итак, приступим…
Немного отойду от темы роутов. Мы с Вами создаем базу книг, в которой будет:
- Сама база книг (frontend)
- Административная часть из которой мы будем добавлять различную информацию (backend)
Так, вот вся информация, которая касается frontend будет лежать:
- Контроллеры в ./application/classes/controller
- Модели в ./application/classes/model
- Шаблоны (виды) в ./application/views
А информация, которая касается backend (административной части) будет лежать:
- Контроллеры в ./application/classes/controller/admin
- Модели в ./application/classes/model/admin
- Шаблоны (виды) в ./application/views/admin
Давайте приступим к реализации нашего проекта и для начала создадим папку admin в ./application/classes/controler, затем папку admin создадим в ./application/classes/model и создадим папку admin в ./application/views
Теперь создадим в ./application/classes/controller контролер для нашего сайта index и в нем создадим экшн index. Наш файл index.php имеет следующее содержание:
<!--?php defined('SYSPATH') or die('No direct script access.'); class Controller_Index extends Controller_Template { public $template = 'index'; public function action_index() { $books = Model::factory('books')->all_books(); $this->template->content = View::factory('allbooks', array( 'books'=>$books,)); } }
</pre>
<p>Теперь создадим модель books и в нем метод all_books. В папке ./application/classes/model создадим файл books.php и поместим в него следующий код:</p>
<pre>
<?php defined('SYSPATH') or die('No direct script access.'); class Model_Books extends Model { public function all_books(){ return array( 'Книга_1' => "Автор_1" , 'Книга_2' => "Автор_2", 'Книга_3' => "Автор_3",); } }
</pre>
<p>Наша модель пока не работает с базой данных, но это мы исправим в ближайшем посте, так что не забывайте подписываться на обновления блога, чтобы ничего не пропустить.<br ?—>
Создадим представление для нашего сайта. В директории ./application/views создадим два файла index.php и allbooks.php.
Содержание файла index.php
</pre> <h1>База книг</h1> <hr /> <pre> <!--?php echo $content; ?-->
Содержание файла allbooks.php:
</pre> НазваниеАвтор <table border="1"> <thead></thead> <tbody><!--?php foreach ($books as $book => $author) { ?--> <tr> <td></td> <td></td> </tr> <!--?php }; ?--></tbody> </table> <pre>
Думаю, что пояснять не надо как мы создали файлы и, что означает написанное в файлах. Если Вы что-то не поняли, то обязательно прочтите статьи “Принцип работы Kohana” и “Принцип работы Kohana (практика)”.
Теперь нам необходимо, чтобы при переходе по адресу http://books у нас обрабатывался контроллер index, а в нем action index. Для этого нам необходимо изменить роут в bootstrap.php. Если Вы не знаете за, что отвечает файл bootstrap.php, то я Вам советую прочитать мой предыдущий пост “Настройка Kohana”
Роут по умолчанию
Если Вы зайдете в bootsrap.php и перейдете в раздел, где описываются роуты Вы увидите всего одно правило — правило по умолчанию:
Route::set('default', '((/(/)))') ->defaults(array( 'controller' => 'welcome', 'action' => 'index', ));
Данный роут будет выполнен тогда, года Kohana не найдет других подходящих правил для поступившего запроса. Роут по умолчанию — это общее правило для обработки запроса.
Что же все-таки происходит. Вызывается метод set класса route, который передаются несколько параметров:
- Первый параметр — название правила, в нашем случае default
- Второй параметр — правило. И тут следует остановиться. Все, что указано в круглых скобках не обязательно, но обязательно нужно соблюдать вложенность скобок, т.е, если есть контроллер и нет action, то и id не будет. Что находится в треугольных скобках — это значение переменной. Если эти скобки убрать, то это правило будет выполняться, если данный сегмент запроса будет строго совпадать с описанием. Т.е. если мы пропишем следующее правило ‘test(/<action>(/<id>)’, то данному правилу будет соответствовать следующий запрос http://books/test/<все, что угодно или не быть>/<все что угодно или не быть> Косая черта — это разделитель, вместо косой черты Вы можете поставить все, что угодно, например подчеркивание и тогда адрес будет выглядеть следующим образом http://books/example_hello.
- И третий (не обязательный параметр) — рекурсивное выражение, которое передается ввиде массива array(<переменная, которую мы проверяем>=> рекурсивное выражение
У метода set вызывается функция default, которой в качестве параметров передается массив со значениями. Данная функция указывает, что необходимо делать kohana при совпадении запроса с правилом, но в запросе не указаны параметры (такие как controller, action и id) В нашем случая будет загружен контроллер welcom и запущен action index.
Давайте сделаем так, что бы по умолчанию загружался контроллер index и выполнялся action index. Для этого изменим роут по умолчанию следующим образом:
Route::set('default', '((/(/)))') ->defaults(array( 'controller' => 'index', 'action' => 'index', ));
Давайте проверим, что у нас получилось. Перейдем по адресу http://books и увидим:
Отлично получилось то, что мы хотели. Для закрепления этого понятия давайте посмотрим небольшое видео:
[youtube_sc url=»http://www.youtube.com/watch?v=c0O9nD-JNMA&feature=youtu.be»]
Теперь давайте создадим контроллер index с action’ом index в ./application/classes/controller/admin , который будет содержать следующий код:
<!--?php defined('SYSPATH') or die('No direct script access.'); class Controller_Admin_Index extends Controller_Template { public $template = 'index'; public function action_index(){ $this--->template->content = 'Это административная часть.'; } }
</pre>
<p>Теперь, если мы перейдем по ссылке http://books/admin, то увидим: <a href=»http://web-programming.com.ua/wp-content/uploads/028.png»><img class=»aligncenter size-full wp-image-627″ title=»02″ src=»http://web-programming.com.ua/wp-content/uploads/028.png» alt=»Создание роута в Kohane» width=»716″ height=»182″ ?—>Ошибка! Правильно, согласно нашему роуту по умолчанию, а он у нас единственный, kohana ищет контроллер admin, а его естественно нет. Нам нужно, чтобы при запросе вида:
http://books/admin/
Загружался по умолчанию контроллер index, который расположен в ./application/classes/controller/admin и выполнял экшн index, а если после admin идет контроллер, экшн и параметр, то загружался соответствующий контроллер, выполнялся соответствующий экшн с переданным параметром. Для этого нам необходимо составить роут.
Создание роута с предопределенным параметром
Открываем наш bootstrap.php и начинаем составлять новое правило. Хочу сразу отметить, что более частные роуты должны стоять выше, чем более общие. Т.е. самый общий роут — это роут по умолчанию должен находиться в самом низу. Это связано с тем, что kohana читает роуты сверху вниз и как только запрос попадает под правило начинает его исполнять.
Давайте напишем наше правило:
Route::set('admin', 'admin((/(/)))') ->defaults(array( 'controller' => 'index', 'action' => 'index', 'directory' => 'admin', ));
Давайте рассмотрим, что мы сделали. Данному правилу дали имя admin, а само правило записали admin/(<controller>(/<action>(/<id>))) , которое означает, что после адреса сайта идет обязательный параметр admin, а дальше идут необязательные параметры controller, action и id. А в значениях по умолчанию появился еще один параметр directory, в котором мы указываем директорию, где находятся контроллеры. Теперь, если после адреса сайта идет admin, то все контроллеры будут загружаться из ./application/classes/controller/admin. Давайте проверим, перейдем по адресу http://books/admin и увидим:
Все работает.
Следующая задача: нам необходимо сделать авторизацию для попадания в административную часть нашей базы. За это будет отвечать контроллер authentication, который будет находиться в ./application/classes/ А экшн login отвечает за авторизацию, экшн logout — за разлогинивание. Но пока мы не будем реализовывать данную функциональность, нам пока не хватает знаний.
Создадим файл authentication.php в ./application/classes, в котором опишим в action:
- login — пока будет выводить запись “Вы успешно залогинились”
- Logout — будет выводить “Вы разлогинились”
Код authentication.php:
<!--?php defined('SYSPATH') or die('No direct script access.'); class Controller_Authentication extends Controller_Template { public $template = 'index'; public function action_login() { $this->template->content = 'Вы успешно залогинились'; } public function action_logout() { $this->template->content = 'Вы успешно разлогинились'; } }
</pre>
<p>Теперь для того, чтобы вызвать экшн авторизации в контроллере authentication необходимо перейти по адресу: http://books/authentication/login. А для разлогинивания — http://boogs/logout. Но, на мой взгляд это не очень красиво, лучше бы для авторизации была следующая ссылка http://books/login, а для ралогинивания — http://books/logout.<br ?—>
Реализовать это просто, как Вы знаете из вышесказанного, необходимо прописать два роута
Route::set('login', 'login') ->defaults(array( 'controller' => 'authentication', 'action' => 'login', ));
и второй:
Route::set('logout', 'logout') ->defaults(array( 'controller' => 'authentication', 'action' => 'logout', ));
Давайте проверим. Введем адрес http://books/login и посмотрим, что получилось:
Получилось, теперь перейдем по адресу http://books/logout и посмотрим, что получилось:
Отлично, все работает. Но мы использовали целых два правила! А это лишняя нагрузка на наше приложение. Давайте вместо этих двух роутов напишем один, используя регулярное выражение.
Использование регулярного выражения в роуте
Удалим два наших правила: login и logout и создадим вместо них следующее:
Route::set('authentication', '',array('action' => 'login|logout',)) ->defaults(array( 'controller' => 'authentication', ));
Давайте подробно посмотрим, что мы прописали в нашем правиле. В метод set класса route мы передаем первым параметром название authentication, вторым параметром само правило, которому будет соответствовать запрос и третий параметр — это регулярное выражение (в нашем случае мы говорим, что action должен принимать один из обязательных аргументов login или logout). О регулярных выражениях Вы можете подробно почитать в статье Регулярные выражения PHP
Итак, мы с вами создали три правила для Kohana, по которым Kohana обрабатывает поступившие запросы. В дальнейшем мы еще добавим роуты, а пока для нашего проекта нам достаточно. Теперь давайте посмотрим небольшое видео, в котором я попытаюсь наглядно продемонстрировать работу роутов.
[youtube_sc url=»http://www.youtube.com/watch?v=yw0m2Ees4R4&feature=youtu.be»]
Мы с Вами познакомились с основами Kohana и в следующих статьях мы начнем создавать уже реальный проект. Походу создания проекта на Kohana мы будем углублять свои знания в фреймворке Kohana. А пока все. И не забывайте подписываться на RSS-рассылку данного блога или ищите меня в Twitter. А на странице в фейсбуке Вы найдете много полезной информации по WEB-программированию.
Скачать исходники данной статьи можно отсюда или отсюда
В последнем роуте маленькая ошибочка: в пустых кавычках должно быть
Зачем? Там не должно ничего быть. Если у нас будет в адресе
/login, то мы перейдем в контроллер authentication и
выполниться экшин login согласно правилу
в kohana 3.3 не работает последний роут,
Добавь в пустых кавычках »
добавь в пустые кавычки
второй action лишний. Его при публикации добавила проверка.
Спасибо автору за работу, все прекрасно разжевано. Для моего уровня самое то.
Кто знает как написать роут в Kohana чтобы страницы имели вид не
site.com/page1, site.com/page2,
а
page1.site.com, page2.site.com ?
Возможно ли это?