Роуты — это функционал, который сопоставляет набранный URL-адрес с действием контроллера. Роуты были добавлены в CakePHP, чтобы сделать адреса более настраиваемыми и гибкими. Если вы используете Apache и mod_rewrite, то роуты можно и не использовать, но все же их использование позволит куда большую гибкость, чем при стандартных средствах.
В CakePHP 1.2 функциональность роутов была сильно расширена.
Прежде чем создавать свои роуты, вы должны узнать какие в CakePHP есть роуты по умолчанию. Изначально CakePHP будет понимать «красивые» адреса в любом приложении. Для того чтобы вызвать какое-то действие — достаточно просто указать в адресе его имя. Именно таким же образом можно передать параметры в это действие.
http://example.com/controller/action/param1/param2/param3
URL /posts/view будет переадресован к методу view() контроллера PostsController, URL /products/viewClearance — к методу view_clearance() контроллера ProductsController. Если в URL действие не объявлено, то переадресация идет к методу index().
Стандартная маршрутизация также позволяет в URL передавать параметры в действия. Например URL /posts/view/25 будет означать вызов функции view(25) класса PostsController.
В CakePHP 1.2 появилась возможность называть параметры. Можно дать параметру имя и отправить его значение при помощи URL. Запрос на адрес /posts/view/title:first+post/category:general приведет к обращению к действию view() контроллера PostsController. Внутри действия вы можете обратиться к переданным параметрам, как к $this->passedArgs['title'] и $this->passedArgs['category'].
Некоторое резюме роутов по умолчанию, которые могут быть вам полезны:
URL: /monkeys/jump
Переадресация: MonkeysController->jump();
URL: /products
Переадресация: ProductsController->index();
URL: /tasks/view/45
Переадресация: TasksController->view(45);
URL: /donations/view/recent/2001
Переадресация: DonationsController->view('recent', '2001');
URL: /contents/view/chapter:models/section:associations
Переадресация: ContentsController->view();
$this->passedArgs['chapter'] = 'models';
$this->passedArgs['section'] = 'associations';
Определение своих роутов позволит вам определить как ваше приложение должно реагировать на тот или иной URL. Определите свои собственные роуты в файле /app/config/routes.php, используя метод Router::connect().
Метод connect() принимает до трех параметров: URL, при котором срабатывает роут, значение по умолчанию для любых элементов запроса и регулярное выражение, призванное помочь роуту найти необходимые части URL.
Router::connect(
'URL',
array('paramName' => 'defaultValue'),
array('paramName' => 'matchingRegex')
)
Первый параметр сообщает маршрутизатору какие URL вы хотите контролировать. URL должен представлять из себя обычную строку адреса, разделенную слешами, так же может содержать место подстановки (обозначено звездочкой (*)) или произвольный элемент роута (часть URL с двоеточием вначале). Использование символа подстановки сообщает роутам какие части адреса вы хотите разбирать, а использование произвольных элементов (тех, что с двоеточием) показывает какие части вы хотите передавать в действия контроллера.
После того, как вы указали адрес, вы используете два последних параметра connect(), чтобы указать элементы, которые необходимо искать в адресе, если он совпал. Второй параметр представляет из себя ассоциативный массив. Ключами в этом массиве являются элементы определенные вами в адресе (те, что двоеточием вначале) или стандартные элементы роутов: :controller, :action, and :plugin. Значениями будут значения определенные вами по умолчанию для этих элементов. Давайте посмотрим на некоторые примеры, чтобы все стало ясно, перед тем как начнем использовать третий параметр connect().
Router::connect(
'/pages/*',
array('controller' => 'pages', 'action' => 'display')
);
Этот роут уже написан в файле routes.php дистрибутива CakePHP (на 40 строке). Он применяется к любому URL, который начинается на /pages/. Роут переадресует CakePHP к действию display() контроллера PagesController(). Например, запрос /pages/products будет отправлен к PagesController->display('products').
Router::connect(
'/government',
array('controller' => 'products', 'action' => 'display', 5)
);
Это второй пример, который показывает как вы можете использовать второй параметр при определении роута для задания значений по умолчанию. Если вы создаете сайт, который предлагает продукты для разных категорий покупателей, то можете создать удобный роут. Вместо длинной и непонятной ссылки /products/display/5 пользователи будут использовать /government.
Для дополнительной гибкости вы можете определить собственные элементы роута. Таким образом можно указать какие элементы в URL могут быть неверными. Когда запрос выполняется, то значения для элементов пользовательских роутов расположены в переменной контроллера $this->params. Это заметно при обработке : именованные параметры (/controller/action/name:value) будут искаться с помощью $this->passedArgs, тогда как данные роутинга будут доступны так: $this->params. Когда объявляете собственный роутинг, следует задать правило для его обработки, что бы CakePHP знал, правильно сформирован запрос или нет.
Router::connect(
'/:controller/:id',
array('action' => 'view'),
array('id' => '[0-9]+')
);
Этот простой пример показывает, как создать переадресацию на контроллер URL вида /controllername/id. URL обрабатывается функцией connect() с двумя параметрами: :controller и :id. Элемент :controller стандартный элемент роутинга в CakePHP, так как обычно имя контроллера находится в URL. Элемент :id является передаваемым параметром. Происходит проверка его соответствия шаблону, заданному в третьем параметре функции connect(). Это говорит CakePHP, как различить ID в URL и не спутать с чем-то другим.
После объявления роутинга, запрос /apples/5 будет аналогичен /apples/view/5. Оба вызывают метод view() в контроллере. Внутри метода view() доступ к значению ID производится так: $this->params[‘id’].
Вот еще один пример:
Router::connect(
'/:controller/:year/:month/:day',
array('action' => 'index', 'day' => null),
array(
'year' => '[12][0-9]{3}',
'month' => '(0[1-9]|1[012])',
'day' => '(0[1-9]|[12][0-9]|3[01])'
)
);
Это показывает, как можно создавать действительно сложные комбинации. В данном примере четыре параметра. Первый параметр нам знаком: это имя контроллера, которому будет передано управление.
Далее мы задали пару значений по умолчанию: в контроллере будет запущен метод index(). Так же четвертый параметр был задан как опциональный.
И наконец, мы определили правила для обработки и сравнения трех параметров.
После этого, роутинг /articles/2007/02/01, /posts/2004/11/16, и /products/2001/05 (опускаем опциональный параметр) будет вызывать метод index() соответсвующего контроллера, а данный будут в массиве $this->params.
Выделение параметров произошло, и теперь желаете иметь доступ к ним типа $articleID вместо $this->params['id']. Тогда добавим третий параметр-массив в Router::connect().
// some_controller.php
function view($articleID = null, $slug = null) {
// some code here...
}
// routes.php
Router::connect(
// E.g. /blog/3-CakePHP_Rocks
'/blog/:id-:slug',
array('controller' => 'blog', 'action' => 'view'),
array(
// order matters since this will simply map ":id" to $articleID in your action
'pass' => array('id', 'slug'),
'id' => '[0-9]+'
)
)
И теперь можно использовать множество способов, так как Cake знает, как обрабатывать каждый роут.
// view.ctp
// this will return a link to /blog/3-CakePHP_Rocks
<?= $html->link('CakePHP Rocks', array(
'controller' => 'blog',
'action' => 'view',
'id' => 3,
'slug' => Inflector::slug('CakePHP Rocks')
)) ?>
Множество веб-приложений имеет закрытую часть для администрирования. Доступ в нее обычно производится путем ввода URL типа /admin/users/edit/5. В CakePHP роутинг админки может быть задан установкой переменной в конфигурации функции Routing.admin?.
Configure::write('Routing.admin', 'admin');
В контроллере вызовется действие с приставкой admin_. Используя пример, /admin/users/edit/5 вызовет метод admin_edit из контроллера UsersController, передав 5 в качестве параметра.
Так же можно задать ссылку /admin на действие admin_index в контроллере следующим кодом:
Router::connect('/admin', array('controller' => 'pages', 'action' => 'index', 'admin' => true));
Можно использовать подобный роутинг и путем явного задания действия.
Router::connect('/profiles/:controller/:action', array('prefix' => 'profiles', 'profiles' => true));
Любой вызов передаст управление методу с приставкой profiles_. В нашем примере, URL /profiles/users/edit/5 вызовет метод profiles_edit в UsersController. Важно помнить, что HTML хелпер создает ссылки с соблюдением префиксов. Например:
echo $html->link('Edit your profile', array('controller' => 'users', 'action' => 'profiles_edit', 'profiles' => true));
Так же можно создавать комбинированные приставки и вызовы в структуре приложения.
<< Настройка ядра | Custom Inflections >>
Я скорее к тому что встречаю в документации чаще
«Таблица маршрутизации» а не «Таблица роутов».
Здесь она же...
Плюс фраза
«Роуты — это функционал, который сопоставляет набранный URL-адрес с действием контроллера.»
Легче будет читаться когда будет написана как
«Маршруты – связывают набранный URL-адрес с контроллером»
и так далее.
ИЗвените, мне малость неясно.
" array('controller' => 'products', 'action' => 'display', 5)" – вот эта 5 в конце строки, что здесь означает?
Извиняюсь, я пытался сымитировать пример, описанный тут: http://www.ixbt.com/soft/opensource/cakephp.shtml
При попытке добавления новости возникает ошибка
The requested URL /posts/add was not found on this server.
Т.е. управление контроллером не передается ядру.. Вроде все имена написаны по стилям «соглашения». В чем может быть проблема?