Welcome 微信登录

首页 / 网页编程 / PHP / 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// forwardif (!$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 forwardif (($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
<?phprequire_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相关内容感兴趣的读者可查看本站专题:《Zend FrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。