Kohana的路由规则是非常强大的。首先必须确认的是路由的匹配原则是有顺序,当一条路由规则匹配成功时,就停止匹配,也就是说在其后面定义的路由规则将不再被执行,因此最后的一条路由规则几乎可以匹配所有的路由规则,它常常类似于下面这样:
在bootstrap.php文件中:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'home',
'action' => 'index',
));
首先需要明白这些语句的含义。
这条路由的名字叫"default";定义了三个路由键,“controller”、“action”、"id".这三个路由键都不是必须的(因为他们都包含在括号里面。),尖括号里面的值就是路由键的名字。如果输入的url中没有controller将默认的controller是home。路由键的名字可以随便命名,但是“directory”、'controller'、‘action’具有特殊的用意,他们定义了使用哪个controller的那个action,directory定义了controller所在的文件目录。
在路由中我们可以定义正则来限制路由所能匹配的范围。下面的例子是kohana手册中的一些例子,比较实用:
/*
* Authentication shortcuts
*/
Route::set('auth', '<action>',
array(
'action' => '(login|logout)'
))
->defaults(array(
'controller' => 'auth'
));
/*
* Multi-format feeds
* 452346/comments.rss
* 5373.json
*/
Route::set('feeds', '<user_id>(/<action>).<format>',
array(
'user_id' => '\d+',
'format' => '(rss|atom|json)',
))
->defaults(array(
'controller' => 'feeds',
'action' => 'status',
));
/*
* Static pages
*/
Route::set('static', '<path>.html',
array(
'path' => '[a-zA-Z0-9_/]+',
))
->defaults(array(
'controller' => 'static',
'action' => 'index',
));
/*
* You don't like slashes?
* EditGallery:bahamas
* Watch:wakeboarding
*/
Route::set('gallery', '<action>(<controller>):<id>',
array(
'controller' => '[A-Z][a-z]++',
'action' => '[A-Z][a-z]++',
))
->defaults(array(
'controller' => 'Slideshow',
));
/*
* Quick search
*/
Route::set('search', ':<query>', array('query' => '.*'))
->defaults(array(
'controller' => 'search',
'action' => 'index',
));
上面的例子可以看出正确的使用路由可以做许多的事情,上面的例子有一些也比较夸张,例如那个使用大写字母来分离参数的例子我在本机上测试报错,最后search的例子也是报错,估计是服务器设置的问题,不能使用“:”。
路由的匹配是通过正则语法来匹配的。
路由规则中的‘/’就是为了说明各个参数之间是使用'/'来分割的。当然这条默认的路由规则并不能匹配所有的路由规则,比如下面的一条URL地址将会报错:
http://kohana.dev/home/index/123/key/value/key/value
也就是说这条路由规则只能匹配类似下面的这样的
http:kohana.dev/controller/action/id ,如在id的后面再加'/'后面再加参数就不能匹配了
我们可以使用这种方式来纠正这个问题,这种方法也叫做忽略路由溢出
Route::set('default', '(<controller>(/<action>(/<id>(/<params>))))', array('params'=>'.*'))
->defaults(array(
'controller' => 'home',
'action' => 'index',
));
这条路由规则将匹配类似“http://kohana.dev/home/index/123/key/value/key/value”这样的url,这时"params"这个路由值里面将是“key/value/key/value”;我们可以很方便的把这些键值分离出来,类似下面这样:
$params = $this->request->param('params');
$params = explode('/', $params);
$num = 0;
$count = count($params);
$param = array();
while ($num < $count){
$param[$params[$num++]] = $params[$num++];
}
在添加路由时要给其取一个唯一的名字,如果名字相同则后面的路由将覆盖前面的路由规则。从用户手册也可以看出,Kohana是鼓励用户使用多路由的。
下面是一个使用路由规则来加载静态文件(CSS,JS)的实例
首先定义路由规则:
bootstrap.php
// Static file serving (CSS, JS, images)
Route::set('frame/media', 'media/www(/<file>)', array('file' => '.+'))
->defaults(array(
'controller' => 'frame',
'action' => 'media',
'file' => NULL,
));
class Controller_Frame extends Controller_Template {
public $template = 'template';
// Routes
protected $media;
public function before(){
parent::before();
if ($this->request->action() === 'media'){
$this->auto_render = FALSE;
}else {
$this->media = Route::get('frame/media');
}
}
public function after(){
if ($this->auto_render){
$media = Route::get('frame/media');
//Add styles
$this->template->styles = array(
$media->uri(array('file' => 'skins/global.css')) => 'screen', //加载 /media/www/skins/global.css
);
//Add scripts
$this->template->scripts = array(
//$media->uri(array('file'=>'script/common.js'));
);
}
parent::after();
}
} // End Welcome