这几天学习zend,卡在了'Invalid controller specified'的问题上,我不是个随便放弃的人,所以我还是要刨根问底,下面是我这几天通过查手册,做实验得出的解决'Invalid controller specified'错误的几种方法。
首先是这个错误的起因,这个错误其实来源特别简单:
如果请求一个无效的控制器,Zend_Controller_Dispatcher::dispatch() 默认会抛出一个异常。就是没有找到对应的请求控制器,或者控制器的代码有错误。
以下是我得出的解决方法:
1.)$front->setParam('useDefaultControllerAlways', true);
通过设置$front->setParam('useDefaultControllerAlways', true);控制器会自动寻找与之对应的模型,所以你需要按照错误中所描述的路径,建立对应的模型,如果没有模型会继续报错。
2.)对前端开启错误捕获
原理是把dispatch装进错误捕获中,类似c#的错误捕获原理,出错就引导它去别处
$front->throwExceptions(true);try {$front->dispatch();} catch (Exception $e) {// handle exceptions yourself}
3.)对前端开启消息返回
$front->returnResponse(true);$response = $front->dispatch();if ($response->isException()) {$exceptions = $response->getException();// handle exceptions ...} else {$response->sendHeaders();$response->outputBody();}
4.)重写__call方法,如果没有对应的动作就指向默认动作
解决方法:
class My_Controller_Action extends Zend_Controller_Action{public function __call($methodName, $args){if ('Action' == substr($methodName, -6)) {$controller = $this->getRequest()->getControllerName();$url = '/' . $controller . '/index';return $this->_redirect($url);}//throw new Zend_Controller_Action_Exception(sprintf('Method "%s" does not exist and was not trapped in __call()', $methodName), 500);//throw new Exception('Invalid method');}
}
这样就能先判断控制器名称,如果不存在,就去默认动作,这个地方其实我很想给之前加一个默认的动作名称设置的函数,这个里面调用它,就不必做成固定的了。不过又偷了个懒,还是留给大家研究讨论,哈哈。比较改源码还是慎重一点好
5.)与上面这个类似,但是是重构分发器
class My_Controller_PreDispatchPlugin extends Zend_Controller_Plugin_Abstract{public function preDispatch(Zend_Controller_Request_Abstract $request){$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();$controller = $dispatcher->getController($request);if (!$controller) {$controller = $dispatcher->getDefaultControllerName($request);}$action = $dispatcher->getAction($request);
if (!method_exists($controller, $action)) {$defaultAction = $dispatcher->getDefaultAction();$controllerName = $request->getControllerName();$response =Zend_Controller_Front::getInstance()->getResponse();$response->setRedirect('/' . $controllerName .'/' . $defaultAction);$response->sendHeaders();exit;}}}
这个我写的有点废物,因为是直接从官方摘下来的,其实它里面还有很多东西,告诉你吧,你做这样的修改仍然出错,还有很多关联的东西你可能还不知道
比如,默认的会认为你的错误控制器是存在的,在你的controller目录中,存在一个ErrorController.php,还有视图中的error/error.phtml,你创建他们才能保证你的错误处理有的放矢。
例子:
class ErrorController extends Zend_Controller_Action{public function errorAction(){//这里进行错误处理,用respons返回404等错误,不过还要处理
}}
当然不止是错误处理,你要把smarty装上,还需要了解分发器,还有这个问题的重要因素:ViewRenderer
$front->setParam('noViewRenderer', true);//在不用默认控制器的情况下(如smarty),这个设置好,此问题才算彻底解决
所以zend每个错误牵动着很多点,你必须对它们有所了解,我的体验,入门不好入,不过见识过强大的路由功能和ACL,再不好学也要学会,哈哈,废话了,欢迎访问我的小站http://www.sookon.com
之前的一篇废物文章只是让你找找成就感http://www.sookon.com/it/php/188.html,不要当真哦,这样处理问题不行