Yaf
的路由组件包括Yaf_Router
和Yaf_Route_Abstract
request_uri
解析到module
、controller
、action
,以及如何解析用户提交的参数Yaf_Request_Abstract
实例Yaf_Route_Static
,在request_uri
中以 “/” 分割module
、controller
、action
和参数的键和值添加路由有两种方式:通过php程序构造路由协议对象添加,通过配置文件添加。
首先得获取路由,
方法1,通过Yaf_Application
对象:
$router = Yaf_Application::app()->getDispacher()->getRouter();
方法2,直接通过Yaf_Dispatcher
对象:
$router = Yaf_Dispatcher::getInstance()->getRouter();
本质上都是需要通过Yaf_Dispatcher
获取。
然后在执行Yaf_Application
的run()
方法前添加路由:
$simpleRoute = new Yaf_Route_Simple('m', 'c', 'a');
$router->addRoute('simple_route', $simpleRoute);
上面的代码添加了一个Yaf_Route_Simple路由。
这是Yaf的默认路由协议,在request_uri中以 “/” 分割module
、controller
、action
和参数的键和值。如:
/module/controller/action/param1/value1/param2/value2
或
/controller/action/param1/value1/param2/value2
分割处来的第一段,有可能是module
,也有可能是controller
,如果该module
存在,则认为是module
,否则认为是controller
。
为了测试,在application/controllers
目录下定义一个UserController
,不属于模块。在application/modules/controllers/app
目录下定义一个GoodsController
,属于app
模块。
* 没有模块的情形(其实是默认模块 index)
访问user控制器:/user/index/a/1/b/1
解析正常。参数a的值为1,b的值为2。
Yaf_Route_Simple
路由协议从query_string
中解析出module
、controller
和action
,自然用户提交的参数也不例外。
形式如下:
?m=module&c=controller&a=action¶m1=value1¶m2=value2
创建Yaf_Route_Simple
时,需要指定query_string
中表示module
、controller
和action
的参数名。
将如下代码加在入口文件index.php的$app->run();
之前
$router = Yaf_Application::app()->getDispatcher()->getRouter();
$simpleRoute = new Yaf_Route_Simple('m', 'c', 'a');
$router->addRoute('simple_route', $simpleRoute);
以上代码表示,query_string
中,m参数的值就是module
,c参数的值就是controller,a参数的值就是action
。如果有的参数没有值,则取默认值。
访问yaf.cc?m=app&c=goods&id=3,测试一下:
成功定位到了app
模块下的goods
控制器中的index
方法(默认),参数id也解析成功。
Yaf_Route_Supervar
是从一个query_string
参数变量中解析module
、controller
、action
和params参数,解析规则同Yaf_Route_Static
。
形如:
?r=/module/controller/action/param1/value1/param2/value2
还是举个例子好:
$supervarRoute = new Yaf_Route_Supervar('r');
$router->addRoute('supervar_route', $supervarRoute);
接上面的例子,在入口文件index.php中添加以上代码。该代码表示表示从”r” 参数中解析module
、controller
、action
和params参数。
访问yaf.cc/?r=/app/goods/index/c/1/d/2 测试一下:
成功定位到了app模块下的goods控制器中的index方法,另外参数c、d也解析出来了。
顾名思义,该路由协议是通过正则表达式匹配request_uri
,创建Yaf_Route_Regex
路由协议时,每个正则表达式都必须指定一个module
、controller
、action
组合。
在入口文件index.php中添加如下代码:
$regexRoute = new Yaf_Route_Regex(
'#product/([0-9]+)/([0-9]+)#', // 必须要用定界符(本例子为"#"),否则报错。鸟哥的Yaf手册中,该例子的正则表达式没有用定界符。版本原因?
array(
'module' => 'app',
'controller' => 'goods',
'action' => 'detail',
),
array(
1 => 'cid',
2 => 'id'
)
);
$router->addRoute('regex_route', $regexRoute);
该路由匹配如下形式的request_uri
:product/1, product/2, product/12。
匹配到之后,定位的模块为app
,控制器为goods
,动作为detail
。array(1=>'id')
表示([0-9]+)这个正则表达式匹配到的值作为参数id的值传给detail
方法。
app模块中GoodController的detailAction代码如下:
public function detailAction($cid, $id)
{
Yaf_Application::app()->getDispatcher()->disableView();
echo "Method: ", __METHOD__, "
";
echo "Params: ";
print_r($this->getRequest()->getParams());
echo "
";
echo "cid=", $cid, ", id=", $id;
}
访问:yaf.cc/product/1/105,结果如下:
该路由协议是通过某种模式来匹配request_uri
,与Yaf_Route_Regex
类似,创建Yaf_Route_Rewrite
路由协议时,每个模式都必须指定一个module、controller、action组合。
该路由协议可看成是弱正则的路由协议。
在入口文件index.php中添加如下代码:
$rewriteRoute = new Yaf_Route_Rewrite(
'user/:name',
array(
'controller' => 'user',
'action' => 'index'
)
);
$router->addRoute('rewrite_route', $rewriteRoute);
该路由协议将形如/user/a, /user/bc, /user/1 之类的request_uri
定位到user
控制器的index
方法。
访问:yaf.cc/user/lcy/id/3,结果如下:
控制器和动作定位都OK,lcy这个参数解析出来了,不过另外一种形式的参数/id/3
却没解析出来。如果要解析这种形式的参数,必须把模式改成
'user/:name/*'
*是通配符,统一匹配剩下的所有参数。
id 已经解析出来了。
关于Yaf
的路由,先就学这么多,其实默认路由就很够用了。个人认为路由要简单,不要搞得太复杂,以至于几个月之后自己都看不懂了,还是要专心于业务逻辑上。