php教程

超轻量级php框架startmvc

Zend Framework教程之Zend_Controller_Plugin插件用法详解

更新时间:2020-03-08 03:25:14 作者:startmvc
本文实例讲述了ZendFramework教程之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 Framework Zend_Controller_Plugin 插件