这几天学习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,不要当真哦,这样处理问题不行
|