Zend Framework教程之Zend_Controller_Plugin插件用法详解
本文实例讲述了Zend Framework教程之Zend_Controller_Plugin插件用法。分享给大家供大家参考,具体如下
通过Zend_Controller_Plugin可以向前端控制器增加附加的功能。便于w一些特殊功能。以下是Zend_Controller_Plugin的简单介绍。
Zend_Controller_Plugin的基本实现
├── Plugin
│ ├── Abstract.php
│ ├── ActionStack.php
│ ├── Broker.php
│ ├── ErrorHandler.php
│ └── PutHandler.php
Zend_Controller_Plugin_Abstract
abstract class Zend_Controller_Plugin_Abstract { protected $_request; protected $_response; public function setRequest(Zend_Controller_Request_Abstract $request) { $this->_request = $request; return $this; } public function getRequest() { return $this->_request; } public function setResponse(Zend_Controller_Response_Abstract $response) { $this->_response = $response; return $this; } public function getResponse() { return $this->_response; } / Called before Zend_Controller_Front begins evaluating the request against its routes. @param Zend_Controller_Request_Abstract $request @return void / public function routeStartup(Zend_Controller_Request_Abstract $request) {} / Called after Zend_Controller_Router exits. Called after Zend_Controller_Front exits from the router. @param Zend_Controller_Request_Abstract $request @return void / public function routeShutdown(Zend_Controller_Request_Abstract $request) {} / Called before Zend_Controller_Front enters its dispatch loop. @param Zend_Controller_Request_Abstract $request @return void / public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) {} / Called before an action is dispatched by Zend_Controller_Dispatcher. This callback allows for proxy or filter behavior. By altering the request and resetting its dispatched flag (via {@link Zend_Controller_Request_Abstract::setDispatched() setDispatched(false)}), the current action may be skipped. @param Zend_Controller_Request_Abstract $request @return void / public function preDispatch(Zend_Controller_Request_Abstract $request) {} / Called after an action is dispatched by Zend_Controller_Dispatcher. This callback allows for proxy or filter behavior. By altering the request and resetting its dispatched flag (via {@link Zend_Controller_Request_Abstract::setDispatched() setDispatched(false)}), a new action may be specified for dispatching. @param Zend_Controller_Request_Abstract $request @return void / public function postDispatch(Zend_Controller_Request_Abstract $request) {} / Called before Zend_Controller_Front exits its dispatch loop. @return void / public function dispatchLoopShutdown() {} }
Zend_Controller_Plugin_Abstract声明定义了Zend_Controller运行过程中的几个关键事件位置。用户可以通过指定的方法,对指定位置的请求和相应对象进行相关操作。
Zend_Controller_Plugin_Abstract中方法的描述如下
routeStartup() 在 Zend_Controller_Front 向注册的 路由器 发送请求前被调用。
routeShutdown()在 路由器 完成请求的路由后被调用。
dispatchLoopStartup() 在 Zend_Controller_Front 进入其分发循环(dispatch loop)前被调用。
preDispatch() 在动作由 分发器 分发前被调用。该回调方法允许代理或者过滤行为。通过修改请求和重设分发标志位(利用 Zend_Controller_Request_Abstract::setDispatched(false) )当前动作可以跳过或者被替换。
postDispatch() 在动作由 分发器 分发后被调用。该回调方法允许代理或者过滤行为。通过修改请求和重设分发标志位(利用 Zend_Controller_Request_Abstract::setDispatched(false) )可以指定新动作进行分发。
dispatchLoopShutdown() 在 Zend_Controller_Front 推出其分发循环后调用。
Zend_Controller_Plugin提供的默认插件:
Zend_Controller_Plugin_Broker:插件经纪人,用于注册,管理自定义的Zend_Controller插件。具体用法,可以参考类代码。
Zend_Controller_Plugin_ActionStack:用于管理动作堆栈。具体用法,可以参考类代码。
Zend_Controller_Plugin_ErrorHandler:用来处理抛出的异常。具体用法,可以参考类代码。
Zend_Controller_Plugin_PutHandler:用于处理请求操作 PUT 。具体用法,可以参考类代码。
Zend_Controller_Plugin_Broker
<?php / Zend_Controller_Plugin_Abstract / require_once 'Zend/Controller/Plugin/Abstract.php'; class Zend_Controller_Plugin_Broker extends Zend_Controller_Plugin_Abstract { protected $_plugins = array(); / Register a plugin. @param Zend_Controller_Plugin_Abstract $plugin @param int $stackIndex @return Zend_Controller_Plugin_Broker / public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null) { if (false !== array_search($plugin, $this->_plugins, true)) { require_once 'Zend/Controller/Exception.php'; throw new Zend_Controller_Exception('Plugin already registered'); } $stackIndex = (int) $stackIndex; if ($stackIndex) { if (isset($this->_plugins[$stackIndex])) { require_once 'Zend/Controller/Exception.php'; throw new Zend_Controller_Exception('Plugin with stackIndex "' . $stackIndex . '" already registered'); } $this->_plugins[$stackIndex] = $plugin; } else { $stackIndex = count($this->_plugins); while (isset($this->_plugins[$stackIndex])) { ++$stackIndex; } $this->_plugins[$stackIndex] = $plugin; } $request = $this->getRequest(); if ($request) { $this->_plugins[$stackIndex]->setRequest($request); } $response = $this->getResponse(); if ($response) { $this->_plugins[$stackIndex]->setResponse($response); } ksort($this->_plugins); return $this; } / Unregister a plugin. @param string|Zend_Controller_Plugin_Abstract $plugin Plugin object or class name @return Zend_Controller_Plugin_Broker / public function unregisterPlugin($plugin) { if ($plugin instanceof Zend_Controller_Plugin_Abstract) { // Given a plugin object, find it in the array $key = array_search($plugin, $this->_plugins, true); if (false === $key) { require_once 'Zend/Controller/Exception.php'; throw new Zend_Controller_Exception('Plugin never registered.'); } unset($this->_plugins[$key]); } elseif (is_string($plugin)) { // Given a plugin class, find all plugins of that class and unset them foreach ($this->_plugins as $key => $_plugin) { $type = get_class($_plugin); if ($plugin == $type) { unset($this->_plugins[$key]); } } } return $this; } / Is a plugin of a particular class registered? @param string $class @return bool / public function hasPlugin($class) { foreach ($this->_plugins as $plugin) { $type = get_class($plugin); if ($class == $type) { return true; } } return false; } / Retrieve a plugin or plugins by class @param string $class Class name of plugin(s) desired @return false|Zend_Controller_Plugin_Abstract|array Returns false if none found, plugin if only one found, and array of plugins if multiple plugins of same class found / public function getPlugin($class) { $found = array(); foreach ($this->_plugins as $plugin) { $type = get_class($plugin); if ($class == $type) { $found[] = $plugin; } } switch (count($found)) { case 0: return false; case 1: return $found[0]; default: return $found; } } / Retrieve all plugins @return array / public function getPlugins() { return $this->_plugins; } / Set request object, and register with each plugin @param Zend_Controller_Request_Abstract $request @return Zend_Controller_Plugin_Broker / public function setRequest(Zend_Controller_Request_Abstract $request) { $this->_request = $request; foreach ($this->_plugins as $plugin) { $plugin->setRequest($request); } return $this; } / Get request object @return Zend_Controller_Request_Abstract $request / public function getRequest() { return $this->_request; } / Set response object @param Zend_Controller_Response_Abstract $response @return Zend_Controller_Plugin_Broker / public function setResponse(Zend_Controller_Response_Abstract $response) { $this->_response = $response; foreach ($this->_plugins as $plugin) { $plugin->setResponse($response); } return $this; } / Get response object @return Zend_Controller_Response_Abstract $response / public function getResponse() { return $this->_response; } / Called before Zend_Controller_Front begins evaluating the request against its routes. @param Zend_Controller_Request_Abstract $request @return void / public function routeStartup(Zend_Controller_Request_Abstract $request) { foreach ($this->_plugins as $plugin) { try { $plugin->routeStartup($request); } catch (Exception $e) { if (Zend_Controller_Front::getInstance()->throwExceptions()) { throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); } else { $this->getResponse()->setException($e); } } } } / Called before Zend_Controller_Front exits its iterations over the route set. @param Zend_Controller_Request_Abstract $request @return void / public function routeShutdown(Zend_Controller_Request_Abstract $request) { foreach ($this->_plugins as $plugin) { try { $plugin->routeShutdown($request); } catch (Exception $e) { if (Zend_Controller_Front::getInstance()->throwExceptions()) { throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); } else { $this->getResponse()->setException($e); } } } } / Called before Zend_Controller_Front enters its dispatch loop. During the dispatch loop, Zend_Controller_Front keeps a Zend_Controller_Request_Abstract object, and uses Zend_Controller_Dispatcher to dispatch the Zend_Controller_Request_Abstract object to controllers/actions. @param Zend_Controller_Request_Abstract $request @return void / public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) { foreach ($this->_plugins as $plugin) { try { $plugin->dispatchLoopStartup($request); } catch (Exception $e) { if (Zend_Controller_Front::getInstance()->throwExceptions()) { throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); } else { $this->getResponse()->setException($e); } } } } / Called before an action is dispatched by Zend_Controller_Dispatcher. @param Zend_Controller_Request_Abstract $request @return void / public function preDispatch(Zend_Controller_Request_Abstract $request) { foreach ($this->_plugins as $plugin) { try { $plugin->preDispatch($request); } catch (Exception $e) { if (Zend_Controller_Front::getInstance()->throwExceptions()) { throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); } else { $this->getResponse()->setException($e); // skip rendering of normal dispatch give the error handler a try $this->getRequest()->setDispatched(false); } } } } / Called after an action is dispatched by Zend_Controller_Dispatcher. @param Zend_Controller_Request_Abstract $request @return void / public function postDispatch(Zend_Controller_Request_Abstract $request) { foreach ($this->_plugins as $plugin) { try { $plugin->postDispatch($request); } catch (Exception $e) { if (Zend_Controller_Front::getInstance()->throwExceptions()) { throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); } else { $this->getResponse()->setException($e); } } } } / Called before Zend_Controller_Front exits its dispatch loop. @param Zend_Controller_Request_Abstract $request @return void / public function dispatchLoopShutdown() { foreach ($this->_plugins as $plugin) { try { $plugin->dispatchLoopShutdown(); } catch (Exception $e) { if (Zend_Controller_Front::getInstance()->throwExceptions()) { throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); } else { $this->getResponse()->setException($e); } } } } }
Zend_Controller_Plugin_ActionStack
<?php / Zend_Controller_Plugin_Abstract / require_once 'Zend/Controller/Plugin/Abstract.php'; / Zend_Registry / require_once 'Zend/Registry.php'; class Zend_Controller_Plugin_ActionStack extends Zend_Controller_Plugin_Abstract { / @var Zend_Registry / protected $_registry; / Registry key under which actions are stored @var string / protected $_registryKey = 'Zend_Controller_Plugin_ActionStack'; / Valid keys for stack items @var array / protected $_validKeys = array( 'module', 'controller', 'action', 'params' ); / Flag to determine whether request parameters are cleared between actions, or whether new parameters are added to existing request parameters. @var Bool / protected $_clearRequestParams = false; / Constructor @param Zend_Registry $registry @param string $key @return void / public function __construct(Zend_Registry $registry = null, $key = null) { if (null === $registry) { $registry = Zend_Registry::getInstance(); } $this->setRegistry($registry); if (null !== $key) { $this->setRegistryKey($key); } else { $key = $this->getRegistryKey(); } $registry[$key] = array(); } / Set registry object @param Zend_Registry $registry @return Zend_Controller_Plugin_ActionStack / public function setRegistry(Zend_Registry $registry) { $this->_registry = $registry; return $this; } / Retrieve registry object @return Zend_Registry / public function getRegistry() { return $this->_registry; } / Retrieve registry key @return string / public function getRegistryKey() { return $this->_registryKey; } / Set registry key @param string $key @return Zend_Controller_Plugin_ActionStack / public function setRegistryKey($key) { $this->_registryKey = (string) $key; return $this; } / Set clearRequestParams flag @param bool $clearRequestParams @return Zend_Controller_Plugin_ActionStack / public function setClearRequestParams($clearRequestParams) { $this->_clearRequestParams = (bool) $clearRequestParams; return $this; } / Retrieve clearRequestParams flag @return bool / public function getClearRequestParams() { return $this->_clearRequestParams; } / Retrieve action stack @return array / public function getStack() { $registry = $this->getRegistry(); $stack = $registry[$this->getRegistryKey()]; return $stack; } / Save stack to registry @param array $stack @return Zend_Controller_Plugin_ActionStack / protected function _saveStack(array $stack) { $registry = $this->getRegistry(); $registry[$this->getRegistryKey()] = $stack; return $this; } / Push an item onto the stack @param Zend_Controller_Request_Abstract $next @return Zend_Controller_Plugin_ActionStack / public function pushStack(Zend_Controller_Request_Abstract $next) { $stack = $this->getStack(); array_push($stack, $next); return $this->_saveStack($stack); } / Pop an item off the action stack @return false|Zend_Controller_Request_Abstract / public function popStack() { $stack = $this->getStack(); if (0 == count($stack)) { return false; } $next = array_pop($stack); $this->_saveStack($stack); if (!$next instanceof Zend_Controller_Request_Abstract) { require_once 'Zend/Controller/Exception.php'; throw new Zend_Controller_Exception('ArrayStack should only contain request objects'); } $action = $next->getActionName(); if (empty($action)) { return $this->popStack($stack); } $request = $this->getRequest(); $controller = $next->getControllerName(); if (empty($controller)) { $next->setControllerName($request->getControllerName()); } $module = $next->getModuleName(); if (empty($module)) { $next->setModuleName($request->getModuleName()); } return $next; } / postDispatch() plugin hook -- check for actions in stack, and dispatch if any found @param Zend_Controller_Request_Abstract $request @return void / public function postDispatch(Zend_Controller_Request_Abstract $request) { // Don't move on to next request if this is already an attempt to // forward if (!$request->isDispatched()) { return; } $this->setRequest($request); $stack = $this->getStack(); if (empty($stack)) { return; } $next = $this->popStack(); if (!$next) { return; } $this->forward($next); } / Forward request with next action @param array $next @return void / public function forward(Zend_Controller_Request_Abstract $next) { $request = $this->getRequest(); if ($this->getClearRequestParams()) { $request->clearParams(); } $request->setModuleName($next->getModuleName()) ->setControllerName($next->getControllerName()) ->setActionName($next->getActionName()) ->setParams($next->getParams()) ->setDispatched(false); } }
Zend_Controller_Plugin_ErrorHandler
<?php / Zend_Controller_Plugin_Abstract / require_once 'Zend/Controller/Plugin/Abstract.php'; class Zend_Controller_Plugin_ErrorHandler extends Zend_Controller_Plugin_Abstract { / Const - No controller exception; controller does not exist / const EXCEPTION_NO_CONTROLLER = 'EXCEPTION_NO_CONTROLLER'; / Const - No action exception; controller exists, but action does not / const EXCEPTION_NO_ACTION = 'EXCEPTION_NO_ACTION'; / Const - No route exception; no routing was possible / const EXCEPTION_NO_ROUTE = 'EXCEPTION_NO_ROUTE'; / Const - Other Exception; exceptions thrown by application controllers / const EXCEPTION_OTHER = 'EXCEPTION_OTHER'; / Module to use for errors; defaults to default module in dispatcher @var string / protected $_errorModule; / Controller to use for errors; defaults to 'error' @var string / protected $_errorController = 'error'; / Action to use for errors; defaults to 'error' @var string / protected $_errorAction = 'error'; / Flag; are we already inside the error handler loop? @var bool / protected $_isInsideErrorHandlerLoop = false; / Exception count logged at first invocation of plugin @var int / protected $_exceptionCountAtFirstEncounter = 0; / Constructor Options may include: - module - controller - action @param Array $options @return void / public function __construct(Array $options = array()) { $this->setErrorHandler($options); } / setErrorHandler() - setup the error handling options @param array $options @return Zend_Controller_Plugin_ErrorHandler / public function setErrorHandler(Array $options = array()) { if (isset($options['module'])) { $this->setErrorHandlerModule($options['module']); } if (isset($options['controller'])) { $this->setErrorHandlerController($options['controller']); } if (isset($options['action'])) { $this->setErrorHandlerAction($options['action']); } return $this; } / Set the module name for the error handler @param string $module @return Zend_Controller_Plugin_ErrorHandler / public function setErrorHandlerModule($module) { $this->_errorModule = (string) $module; return $this; } / Retrieve the current error handler module @return string / public function getErrorHandlerModule() { if (null === $this->_errorModule) { $this->_errorModule = Zend_Controller_Front::getInstance()->getDispatcher()->getDefaultModule(); } return $this->_errorModule; } / Set the controller name for the error handler @param string $controller @return Zend_Controller_Plugin_ErrorHandler / public function setErrorHandlerController($controller) { $this->_errorController = (string) $controller; return $this; } / Retrieve the current error handler controller @return string / public function getErrorHandlerController() { return $this->_errorController; } / Set the action name for the error handler @param string $action @return Zend_Controller_Plugin_ErrorHandler / public function setErrorHandlerAction($action) { $this->_errorAction = (string) $action; return $this; } / Retrieve the current error handler action @return string / public function getErrorHandlerAction() { return $this->_errorAction; } / Route shutdown hook -- Ccheck for router exceptions @param Zend_Controller_Request_Abstract $request / public function routeShutdown(Zend_Controller_Request_Abstract $request) { $this->_handleError($request); } / Pre dispatch hook -- check for exceptions and dispatch error handler if necessary @param Zend_Controller_Request_Abstract $request / public function preDispatch(Zend_Controller_Request_Abstract $request) { $this->_handleError($request); } / Post dispatch hook -- check for exceptions and dispatch error handler if necessary @param Zend_Controller_Request_Abstract $request / public function postDispatch(Zend_Controller_Request_Abstract $request) { $this->_handleError($request); } / Handle errors and exceptions If the 'noErrorHandler' front controller flag has been set, returns early. @param Zend_Controller_Request_Abstract $request @return void / protected function _handleError(Zend_Controller_Request_Abstract $request) { $frontController = Zend_Controller_Front::getInstance(); if ($frontController->getParam('noErrorHandler')) { return; } $response = $this->getResponse(); if ($this->_isInsideErrorHandlerLoop) { $exceptions = $response->getException(); if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) { // Exception thrown by error handler; tell the front controller to throw it $frontController->throwExceptions(true); throw array_pop($exceptions); } } // check for an exception AND allow the error handler controller the option to forward if (($response->isException()) && (!$this->_isInsideErrorHandlerLoop)) { $this->_isInsideErrorHandlerLoop = true; // Get exception information $error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); $exceptions = $response->getException(); $exception = $exceptions[0]; $exceptionType = get_class($exception); $error->exception = $exception; switch ($exceptionType) { case 'Zend_Controller_Router_Exception': if (404 == $exception->getCode()) { $error->type = self::EXCEPTION_NO_ROUTE; } else { $error->type = self::EXCEPTION_OTHER; } break; case 'Zend_Controller_Dispatcher_Exception': $error->type = self::EXCEPTION_NO_CONTROLLER; break; case 'Zend_Controller_Action_Exception': if (404 == $exception->getCode()) { $error->type = self::EXCEPTION_NO_ACTION; } else { $error->type = self::EXCEPTION_OTHER; } break; default: $error->type = self::EXCEPTION_OTHER; break; } // Keep a copy of the original request $error->request = clone $request; // get a count of the number of exceptions encountered $this->_exceptionCountAtFirstEncounter = count($exceptions); // Forward to the error handler $request->setParam('error_handler', $error) ->setModuleName($this->getErrorHandlerModule()) ->setControllerName($this->getErrorHandlerController()) ->setActionName($this->getErrorHandlerAction()) ->setDispatched(false); } } }
Zend_Controller_Plugin_PutHandler
<?php require_once 'Zend/Controller/Plugin/Abstract.php'; require_once 'Zend/Controller/Request/Http.php'; class Zend_Controller_Plugin_PutHandler extends Zend_Controller_Plugin_Abstract { / Before dispatching, digest PUT request body and set params @param Zend_Controller_Request_Abstract $request / public function preDispatch(Zend_Controller_Request_Abstract $request) { if (!$request instanceof Zend_Controller_Request_Http) { return; } if ($this->_request->isPut()) { $putParams = array(); parse_str($this->_request->getRawBody(), $putParams); $request->setParams($putParams); } } }
更多关于zend相关内容感兴趣的读者可查看本站专题《》、《》、《》、《》、《》、《》及《》
希望本文所述对大家PHP程序设计有所帮助。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程