ホームページ >バックエンド開発 >PHPチュートリアル >Zend Framework での Zend_Controller_Plugin プラグインの使用法
この記事では、Zend Framework チュートリアルで Zend_Controller_Plugin プラグインの使用法を主に紹介し、サンプル、使用方法、および関連する注意事項の形式で Zend_Controller_Plugin プラグインの原理を詳細に分析します。次へ
この記事の例 Zend Framework チュートリアルで Zend_Controller_Plugin プラグインの使用方法を学習します。参考のために皆さんと共有してください。詳細は次のとおりです。
Zend_Controller_Plugin を通じてフロントエンド コントローラーに関数を追加できます。いくつかの特殊な機能に便利です。以下は 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 がディスパッチ ループに入る前に呼び出されます。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);
}
}
<?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); } } }# 以上がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。 関連する推奨事項:
Zend Framework での Zend_Config コンポーネントの使用法について
Zend Framework での Zend_Db_Table_Rowset の使用法について
以上がZend Framework での Zend_Controller_Plugin プラグインの使用法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。