本文实例讲述了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;
}
public function routeStartup(Zend_Controller_Request_Abstract $request)
{}
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{}
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{}
public function postDispatch(Zend_Controller_Request_Abstract $request)
{}
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
_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;
}
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;
}
public function hasPlugin($class)
{
foreach ($this->_plugins as $plugin) {
$type = get_class($plugin);
if ($class == $type) {
return true;
}
}
return false;
}
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;
}
}
public function getPlugins()
{
return $this->_plugins;
}
public function setRequest(Zend_Controller_Request_Abstract $request)
{
$this->_request = $request;
foreach ($this->_plugins as $plugin) {
$plugin->setRequest($request);
}
return $this;
}
public function getRequest()
{
return $this->_request;
}
public function setResponse(Zend_Controller_Response_Abstract $response)
{
$this->_response = $response;
foreach ($this->_plugins as $plugin) {
$plugin->setResponse($response);
}
return $this;
}
public function getResponse()
{
return $this->_response;
}
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);
}
}
}
}
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);
}
}
}
}
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);
}
}
}
}
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);
}
}
}
}
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);
}
}
}
}
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
setRegistry($registry);
if (null !== $key) {
$this->setRegistryKey($key);
} else {
$key = $this->getRegistryKey();
}
$registry[$key] = array();
}
public function setRegistry(Zend_Registry $registry)
{
$this->_registry = $registry;
return $this;
}
public function getRegistry()
{
return $this->_registry;
}
public function getRegistryKey()
{
return $this->_registryKey;
}
public function setRegistryKey($key)
{
$this->_registryKey = (string) $key;
return $this;
}
public function setClearRequestParams($clearRequestParams)
{
$this->_clearRequestParams = (bool) $clearRequestParams;
return $this;
}
public function getClearRequestParams()
{
return $this->_clearRequestParams;
}
public function getStack()
{
$registry = $this->getRegistry();
$stack = $registry[$this->getRegistryKey()];
return $stack;
}
protected function _saveStack(array $stack)
{
$registry = $this->getRegistry();
$registry[$this->getRegistryKey()] = $stack;
return $this;
}
public function pushStack(Zend_Controller_Request_Abstract $next)
{
$stack = $this->getStack();
array_push($stack, $next);
return $this->_saveStack($stack);
}
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;
}
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);
}
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
setErrorHandler($options);
}
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;
}
public function setErrorHandlerModule($module)
{
$this->_errorModule = (string) $module;
return $this;
}
public function getErrorHandlerModule()
{
if (null === $this->_errorModule) {
$this->_errorModule = Zend_Controller_Front::getInstance()->getDispatcher()->getDefaultModule();
}
return $this->_errorModule;
}
public function setErrorHandlerController($controller)
{
$this->_errorController = (string) $controller;
return $this;
}
public function getErrorHandlerController()
{
return $this->_errorController;
}
public function setErrorHandlerAction($action)
{
$this->_errorAction = (string) $action;
return $this;
}
public function getErrorHandlerAction()
{
return $this->_errorAction;
}
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
$this->_handleError($request);
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$this->_handleError($request);
}
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$this->_handleError($request);
}
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
_request->isPut()) {
$putParams = array();
parse_str($this->_request->getRawBody(), $putParams);
$request->setParams($putParams);
}
}
}
更多关于zend相关内容感兴趣的读者可查看本站专题:《Zend frameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。



