phalcon的controller命名是遵循驼峰规则转换的,比如/article/index-test/index或/article/index_test/index这样的url能被定位到article模块下IndexTestController.php的index方法,但是action不支持驼峰规则,这让从zend framework转过来的我很是不适应,花了2个小时研究,在没看phalcon源码的情况下搞定了这个问题。
首先从router着手,准备在匹配路由时对action变量做处理。在我的项目中router路由写法如下:$router->add('/'.$key.'/:controller/:action/:params',array(
'namespace' => $namespace,
'module' => $key,
'controller' => 1,
'action' => 2,
'params' => 3
)
);
其中$key是我的模块名,通过循环我的模块列表,实现多模块路由配置。
router->add方法的参数是$pattern, $paths , $httpMethods,使用方法如下/**
* Adds a route to the router without any HTTP constraint
*
* $router->add('/about', 'About::index');
*
*
* @param string $pattern
* @param mixed $paths
* @param mixed $httpMethods
* @return \Phalcon\Mvc\Router\RouteInterface
*/
public function add($pattern, $paths = null, $httpMethods = null) {}
想对$action做加工,除非$paths支持回调函数,从官方下载的这个phalcon ide工具包源码看,$paths只支持字符串About::index或数组,不支持回调。此路不通。
接下来,查到router支持convert方法,亦即可以这样使用$router->add('/'.$key.'/:controller/:action/:params',array(
'namespace' => $namespace,
'module' => $key,
'controller' => 1,
'action' => 2,
'params' => 3
)
)->convert('action',function($action){
return $action = str2hump($action);
});
测试不能达到想要的效果,阅读方法说明,convert方法,改的是params值,也就是$this->dispatcher->getParam['action']的值。
看来从路由着手没有好的办法,那就从分发着手。
找出phalcon大拿徐谦(AlloVince)的这篇经典文章http://avnpc.com/pages/phalcon-mvc-process ,找到分发流程的几个断点,先试下dispatch:beforeDispatch$dispatcher = new MvcDispatcher();
$eventsManager = new EventsManager();
$eventsManager->attach("dispatch:beforeDispatch",function($event, $dispatcher) {
$action = $dispatcher->getActionName();
$dispatcher->setActionName(str2hump($action));
});
报EXCEPTION_ACTION_NOT_FOUND错误,意思是找不到action
改成dispatch:beforeDispatchLoop,搞定。
附str2hump函数/*
* str2hump 字符串转驼峰
*/
function str2hump($str){
$tmp_arr = explode("-",$str);
$tmp = array();
foreach($tmp_arr as $key=>$var){
if($key>0){
$tmp[] = ucfirst($var);
}else{
$tmp[] = $var;
}
}
$tmp = implode("",$tmp);
return $tmp;
}