插件简介控制器(Controller)结构包含一个可以在控制器周期内确定事件发生时调用用户代码的插件系统。 前端控制器(Front controller)使用插件 broker 作为用户插件注册,同时插件 broker 确保前端控制器中注册的每个插件都在事件发生时调用相应的事件方法。
事件方法定义在虚类
编写插件
只需要包含并扩展抽象类 class MyPlugin extends Zend_Controller_Plugin_Abstract { // ... }
使用插件
可以使用 class MyPlugin extends Zend_Controller_Plugin_Abstract { public function routeStartup(Zend_Controller_Request_Abstract $request) { $this->getResponse()->appendBody("<p>routeStartup() called</p>\n"); } public function routeShutdown(Zend_Controller_Request_Abstract $request) { $this->getResponse()->appendBody("<p>routeShutdown() called</p>\n"); } public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) { $this->getResponse()->appendBody("<p>dispatchLoopStartup() called</p>\n"); } public function preDispatch(Zend_Controller_Request_Abstract $request) { $this->getResponse()->appendBody("<p>preDispatch() called</p>\n"); } public function postDispatch(Zend_Controller_Request_Abstract $request) { $this->getResponse()->appendBody("<p>postDispatch() called</p>\n"); } public function dispatchLoopShutdown() { $this->getResponse()->appendBody("<p>dispatchLoopShutdown() called</p>\n"); } } $front = Zend_Controller_Front::getInstance(); $front->setControllerDirectory('/path/to/controllers') ->setRouter(new Zend_Controller_Router_Rewrite()) ->registerPlugin(new MyPlugin()); $front->dispatch(); 假设没有动作产生任何输出,而只有一个动作被调用,前面演示的插件仍然会产生下面的输出: <p>routeStartup() called</p> <p>routeShutdown() called</p> <p>dispatchLoopStartup() called</p> <p>preDispatch() called</p> <p>postDispatch() called</p> <p>dispatchLoopShutdown() called</p>
获取和控制插件有时,可能需要取消注册或者获取一个插件。下面列出的前端控制器中的方法可以实现这个功能:
包含在标准发行包中的插件Zend Framework 在其标准发行包中包含错误处理插件。 动作堆栈
你可以在任何时候用
一个附加的方法, Zend_Controller_Plugin_ErrorHandler
插件的基本目标是:
换句话说,
缺省地,在缺省模块中,
另外,你可以传递一个可选的联合数组给可以代理
如果在派遣错误处理器时发生异常,这插件将告诉前端控制器抛出异常,并重新抛出和带响应对象注册的最后一个异常。 使用 ErrorHandler 作为一个 404 处理器(handler)
因为
异常的抓取被记录在一个对象里,这个对象注册在请求里。使用 class ErrorController extends Zend_Controller_Action { public function errorAction() { $errors = $this->_getParam('error_handler'); } }
一旦有错误对象,可通过
然后可以测试头两个类型中的任意一个,并且,如果这样,显示一个404页面: class ErrorController extends Zend_Controller_Action { public function errorAction() { $errors = $this->_getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // 404 error -- controller or action not found $this->getResponse() ->setRawHeader('HTTP/1.1 404 Not Found'); // ... get some output to display... break; default: // application error; display error page, but don't // change status code break; } } }
最后,你可以读取异常,这个异常由错误管理器通过抓取 public function errorAction() { $errors = $this->_getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // 404 error -- controller or action not found $this->getResponse() ->setRawHeader('HTTP/1.1 404 Not Found'); // ... get some output to display... break; default: // application error; display error page, but don't change // status code // ... // Log the exception: $exception = $errors->exception; $log = new Zend_Log( new Zend_Log_Writer_Stream( '/tmp/applicationException.log' ) ); $log->debug($exception->getMessage() . "\n" . $exception->getTraceAsString()); break; } } 处理以前呈现的(rendered)输出
如果你在一个请求里派遣多个动作,或者你的动作对 如果你希望呈现错误内嵌到这样的页面,不需要修改。如果你不希望呈现这样的内容,你应该在呈现任何视图之前清除响应体: $this->getResponse()->clearBody(); 插件用法示例Example #1 Standard usage $front = Zend_Controller_Front::getInstance(); $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler()); Example #2 Setting a different error handler $front = Zend_Controller_Front::getInstance(); $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array( 'module' => 'mystuff', 'controller' => 'static', 'action' => 'error' ))); Example #3 Using accessors $plugin = new Zend_Controller_Plugin_ErrorHandler(); $plugin->setErrorHandlerModule('mystuff') ->setErrorHandlerController('static') ->setErrorHandlerAction('error'); $front = Zend_Controller_Front::getInstance(); $front->registerPlugin($plugin); 错误控制器示例为了使用错误处理器插件,你需要错误控制器。下面是个简单的例子。 class ErrorController extends Zend_Controller_Action { public function errorAction() { $errors = $this->_getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // 404 error -- controller or action not found $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found'); $content =<<<EOH <h1>Error!</h1> <p>The page you requested was not found.</p> EOH; break; default: // application error $content =<<<EOH <h1>Error!</h1> <p>An unexpected error occurred. Please try again later.</p> EOH; break; } // Clear previous content $this->getResponse()->clearBody(); $this->view->content = $content; } }
|