Zend Framework教程之Zend_Controller_Plugin插件用法详解
本文实例讲述了ZendFramework教程之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
abstractclassZend_Controller_Plugin_Abstract { protected$_request; protected$_response; publicfunctionsetRequest(Zend_Controller_Request_Abstract$request) { $this->_request=$request; return$this; } publicfunctiongetRequest() { return$this->_request; } publicfunctionsetResponse(Zend_Controller_Response_Abstract$response) { $this->_response=$response; return$this; } publicfunctiongetResponse() { return$this->_response; } /** *CalledbeforeZend_Controller_Frontbeginsevaluatingthe *requestagainstitsroutes. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionrouteStartup(Zend_Controller_Request_Abstract$request) {} /** *CalledafterZend_Controller_Routerexits. * *CalledafterZend_Controller_Frontexitsfromtherouter. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionrouteShutdown(Zend_Controller_Request_Abstract$request) {} /** *CalledbeforeZend_Controller_Frontentersitsdispatchloop. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctiondispatchLoopStartup(Zend_Controller_Request_Abstract$request) {} /** *CalledbeforeanactionisdispatchedbyZend_Controller_Dispatcher. * *Thiscallbackallowsforproxyorfilterbehavior.Byalteringthe *requestandresettingitsdispatchedflag(via *{@linkZend_Controller_Request_Abstract::setDispatched()setDispatched(false)}), *thecurrentactionmaybeskipped. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionpreDispatch(Zend_Controller_Request_Abstract$request) {} /** *CalledafteranactionisdispatchedbyZend_Controller_Dispatcher. * *Thiscallbackallowsforproxyorfilterbehavior.Byalteringthe *requestandresettingitsdispatchedflag(via *{@linkZend_Controller_Request_Abstract::setDispatched()setDispatched(false)}), *anewactionmaybespecifiedfordispatching. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionpostDispatch(Zend_Controller_Request_Abstract$request) {} /** *CalledbeforeZend_Controller_Frontexitsitsdispatchloop. * *@returnvoid */ publicfunctiondispatchLoopShutdown() {} }
Zend_Controller_Plugin_Abstract声明定义了Zend_Controller运行过程中的几个关键事件位置。用户可以通过指定的方法,对指定位置的请求和相应对象进行相关操作。
Zend_Controller_Plugin_Abstract中方法的描述如下:
routeStartup()在Zend_Controller_Front向注册的路由器发送请求前被调用。
routeShutdown()在路由器完成请求的路由后被调用。
dispatchLoopStartup()在Zend_Controller_Front进入其分发循环(dispatchloop)前被调用。
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'; classZend_Controller_Plugin_BrokerextendsZend_Controller_Plugin_Abstract { protected$_plugins=array(); /** *Registeraplugin. * *@paramZend_Controller_Plugin_Abstract$plugin *@paramint$stackIndex *@returnZend_Controller_Plugin_Broker */ publicfunctionregisterPlugin(Zend_Controller_Plugin_Abstract$plugin,$stackIndex=null) { if(false!==array_search($plugin,$this->_plugins,true)){ require_once'Zend/Controller/Exception.php'; thrownewZend_Controller_Exception('Pluginalreadyregistered'); } $stackIndex=(int)$stackIndex; if($stackIndex){ if(isset($this->_plugins[$stackIndex])){ require_once'Zend/Controller/Exception.php'; thrownewZend_Controller_Exception('PluginwithstackIndex"'.$stackIndex.'"alreadyregistered'); } $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; } /** *Unregisteraplugin. * *@paramstring|Zend_Controller_Plugin_Abstract$pluginPluginobjectorclassname *@returnZend_Controller_Plugin_Broker */ publicfunctionunregisterPlugin($plugin) { if($plugininstanceofZend_Controller_Plugin_Abstract){ //Givenapluginobject,finditinthearray $key=array_search($plugin,$this->_plugins,true); if(false===$key){ require_once'Zend/Controller/Exception.php'; thrownewZend_Controller_Exception('Pluginneverregistered.'); } unset($this->_plugins[$key]); }elseif(is_string($plugin)){ //Givenapluginclass,findallpluginsofthatclassandunsetthem foreach($this->_pluginsas$key=>$_plugin){ $type=get_class($_plugin); if($plugin==$type){ unset($this->_plugins[$key]); } } } return$this; } /** *Isapluginofaparticularclassregistered? * *@paramstring$class *@returnbool */ publicfunctionhasPlugin($class) { foreach($this->_pluginsas$plugin){ $type=get_class($plugin); if($class==$type){ returntrue; } } returnfalse; } /** *Retrieveapluginorpluginsbyclass * *@paramstring$classClassnameofplugin(s)desired *@returnfalse|Zend_Controller_Plugin_Abstract|arrayReturnsfalseifnonefound,pluginifonlyonefound,andarrayofpluginsifmultiplepluginsofsameclassfound */ publicfunctiongetPlugin($class) { $found=array(); foreach($this->_pluginsas$plugin){ $type=get_class($plugin); if($class==$type){ $found[]=$plugin; } } switch(count($found)){ case0: returnfalse; case1: return$found[0]; default: return$found; } } /** *Retrieveallplugins * *@returnarray */ publicfunctiongetPlugins() { return$this->_plugins; } /** *Setrequestobject,andregisterwitheachplugin * *@paramZend_Controller_Request_Abstract$request *@returnZend_Controller_Plugin_Broker */ publicfunctionsetRequest(Zend_Controller_Request_Abstract$request) { $this->_request=$request; foreach($this->_pluginsas$plugin){ $plugin->setRequest($request); } return$this; } /** *Getrequestobject * *@returnZend_Controller_Request_Abstract$request */ publicfunctiongetRequest() { return$this->_request; } /** *Setresponseobject * *@paramZend_Controller_Response_Abstract$response *@returnZend_Controller_Plugin_Broker */ publicfunctionsetResponse(Zend_Controller_Response_Abstract$response) { $this->_response=$response; foreach($this->_pluginsas$plugin){ $plugin->setResponse($response); } return$this; } /** *Getresponseobject * *@returnZend_Controller_Response_Abstract$response */ publicfunctiongetResponse() { return$this->_response; } /** *CalledbeforeZend_Controller_Frontbeginsevaluatingthe *requestagainstitsroutes. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionrouteStartup(Zend_Controller_Request_Abstract$request) { foreach($this->_pluginsas$plugin){ try{ $plugin->routeStartup($request); }catch(Exception$e){ if(Zend_Controller_Front::getInstance()->throwExceptions()){ thrownewZend_Controller_Exception($e->getMessage().$e->getTraceAsString(),$e->getCode(),$e); }else{ $this->getResponse()->setException($e); } } } } /** *CalledbeforeZend_Controller_Frontexitsitsiterationsover *therouteset. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionrouteShutdown(Zend_Controller_Request_Abstract$request) { foreach($this->_pluginsas$plugin){ try{ $plugin->routeShutdown($request); }catch(Exception$e){ if(Zend_Controller_Front::getInstance()->throwExceptions()){ thrownewZend_Controller_Exception($e->getMessage().$e->getTraceAsString(),$e->getCode(),$e); }else{ $this->getResponse()->setException($e); } } } } /** *CalledbeforeZend_Controller_Frontentersitsdispatchloop. * *Duringthedispatchloop,Zend_Controller_Frontkeepsa *Zend_Controller_Request_Abstractobject,anduses *Zend_Controller_Dispatchertodispatchthe *Zend_Controller_Request_Abstractobjecttocontrollers/actions. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctiondispatchLoopStartup(Zend_Controller_Request_Abstract$request) { foreach($this->_pluginsas$plugin){ try{ $plugin->dispatchLoopStartup($request); }catch(Exception$e){ if(Zend_Controller_Front::getInstance()->throwExceptions()){ thrownewZend_Controller_Exception($e->getMessage().$e->getTraceAsString(),$e->getCode(),$e); }else{ $this->getResponse()->setException($e); } } } } /** *CalledbeforeanactionisdispatchedbyZend_Controller_Dispatcher. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionpreDispatch(Zend_Controller_Request_Abstract$request) { foreach($this->_pluginsas$plugin){ try{ $plugin->preDispatch($request); }catch(Exception$e){ if(Zend_Controller_Front::getInstance()->throwExceptions()){ thrownewZend_Controller_Exception($e->getMessage().$e->getTraceAsString(),$e->getCode(),$e); }else{ $this->getResponse()->setException($e); //skiprenderingofnormaldispatchgivetheerrorhandleratry $this->getRequest()->setDispatched(false); } } } } /** *CalledafteranactionisdispatchedbyZend_Controller_Dispatcher. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionpostDispatch(Zend_Controller_Request_Abstract$request) { foreach($this->_pluginsas$plugin){ try{ $plugin->postDispatch($request); }catch(Exception$e){ if(Zend_Controller_Front::getInstance()->throwExceptions()){ thrownewZend_Controller_Exception($e->getMessage().$e->getTraceAsString(),$e->getCode(),$e); }else{ $this->getResponse()->setException($e); } } } } /** *CalledbeforeZend_Controller_Frontexitsitsdispatchloop. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctiondispatchLoopShutdown() { foreach($this->_pluginsas$plugin){ try{ $plugin->dispatchLoopShutdown(); }catch(Exception$e){ if(Zend_Controller_Front::getInstance()->throwExceptions()){ thrownewZend_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'; classZend_Controller_Plugin_ActionStackextendsZend_Controller_Plugin_Abstract { /**@varZend_Registry*/ protected$_registry; /** *Registrykeyunderwhichactionsarestored *@varstring */ protected$_registryKey='Zend_Controller_Plugin_ActionStack'; /** *Validkeysforstackitems *@vararray */ protected$_validKeys=array( 'module', 'controller', 'action', 'params' ); /** *Flagtodeterminewhetherrequestparametersareclearedbetweenactions,orwhethernewparameters *areaddedtoexistingrequestparameters. * *@varBool */ protected$_clearRequestParams=false; /** *Constructor * *@paramZend_Registry$registry *@paramstring$key *@returnvoid */ publicfunction__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(); } /** *Setregistryobject * *@paramZend_Registry$registry *@returnZend_Controller_Plugin_ActionStack */ publicfunctionsetRegistry(Zend_Registry$registry) { $this->_registry=$registry; return$this; } /** *Retrieveregistryobject * *@returnZend_Registry */ publicfunctiongetRegistry() { return$this->_registry; } /** *Retrieveregistrykey * *@returnstring */ publicfunctiongetRegistryKey() { return$this->_registryKey; } /** *Setregistrykey * *@paramstring$key *@returnZend_Controller_Plugin_ActionStack */ publicfunctionsetRegistryKey($key) { $this->_registryKey=(string)$key; return$this; } /** *SetclearRequestParamsflag * *@parambool$clearRequestParams *@returnZend_Controller_Plugin_ActionStack */ publicfunctionsetClearRequestParams($clearRequestParams) { $this->_clearRequestParams=(bool)$clearRequestParams; return$this; } /** *RetrieveclearRequestParamsflag * *@returnbool */ publicfunctiongetClearRequestParams() { return$this->_clearRequestParams; } /** *Retrieveactionstack * *@returnarray */ publicfunctiongetStack() { $registry=$this->getRegistry(); $stack=$registry[$this->getRegistryKey()]; return$stack; } /** *Savestacktoregistry * *@paramarray$stack *@returnZend_Controller_Plugin_ActionStack */ protectedfunction_saveStack(array$stack) { $registry=$this->getRegistry(); $registry[$this->getRegistryKey()]=$stack; return$this; } /** *Pushanitemontothestack * *@paramZend_Controller_Request_Abstract$next *@returnZend_Controller_Plugin_ActionStack */ publicfunctionpushStack(Zend_Controller_Request_Abstract$next) { $stack=$this->getStack(); array_push($stack,$next); return$this->_saveStack($stack); } /** *Popanitemofftheactionstack * *@returnfalse|Zend_Controller_Request_Abstract */ publicfunctionpopStack() { $stack=$this->getStack(); if(0==count($stack)){ returnfalse; } $next=array_pop($stack); $this->_saveStack($stack); if(!$nextinstanceofZend_Controller_Request_Abstract){ require_once'Zend/Controller/Exception.php'; thrownewZend_Controller_Exception('ArrayStackshouldonlycontainrequestobjects'); } $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()pluginhook--checkforactionsinstack,anddispatchifanyfound * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ publicfunctionpostDispatch(Zend_Controller_Request_Abstract$request) { //Don'tmoveontonextrequestifthisisalreadyanattemptto //forward if(!$request->isDispatched()){ return; } $this->setRequest($request); $stack=$this->getStack(); if(empty($stack)){ return; } $next=$this->popStack(); if(!$next){ return; } $this->forward($next); } /** *Forwardrequestwithnextaction * *@paramarray$next *@returnvoid */ publicfunctionforward(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'; classZend_Controller_Plugin_ErrorHandlerextendsZend_Controller_Plugin_Abstract { /** *Const-Nocontrollerexception;controllerdoesnotexist */ constEXCEPTION_NO_CONTROLLER='EXCEPTION_NO_CONTROLLER'; /** *Const-Noactionexception;controllerexists,butactiondoesnot */ constEXCEPTION_NO_ACTION='EXCEPTION_NO_ACTION'; /** *Const-Norouteexception;noroutingwaspossible */ constEXCEPTION_NO_ROUTE='EXCEPTION_NO_ROUTE'; /** *Const-OtherException;exceptionsthrownbyapplicationcontrollers */ constEXCEPTION_OTHER='EXCEPTION_OTHER'; /** *Moduletouseforerrors;defaultstodefaultmoduleindispatcher *@varstring */ protected$_errorModule; /** *Controllertouseforerrors;defaultsto'error' *@varstring */ protected$_errorController='error'; /** *Actiontouseforerrors;defaultsto'error' *@varstring */ protected$_errorAction='error'; /** *Flag;arewealreadyinsidetheerrorhandlerloop? *@varbool */ protected$_isInsideErrorHandlerLoop=false; /** *Exceptioncountloggedatfirstinvocationofplugin *@varint */ protected$_exceptionCountAtFirstEncounter=0; /** *Constructor * *Optionsmayinclude: *-module *-controller *-action * *@paramArray$options *@returnvoid */ publicfunction__construct(Array$options=array()) { $this->setErrorHandler($options); } /** *setErrorHandler()-setuptheerrorhandlingoptions * *@paramarray$options *@returnZend_Controller_Plugin_ErrorHandler */ publicfunctionsetErrorHandler(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; } /** *Setthemodulenamefortheerrorhandler * *@paramstring$module *@returnZend_Controller_Plugin_ErrorHandler */ publicfunctionsetErrorHandlerModule($module) { $this->_errorModule=(string)$module; return$this; } /** *Retrievethecurrenterrorhandlermodule * *@returnstring */ publicfunctiongetErrorHandlerModule() { if(null===$this->_errorModule){ $this->_errorModule=Zend_Controller_Front::getInstance()->getDispatcher()->getDefaultModule(); } return$this->_errorModule; } /** *Setthecontrollernamefortheerrorhandler * *@paramstring$controller *@returnZend_Controller_Plugin_ErrorHandler */ publicfunctionsetErrorHandlerController($controller) { $this->_errorController=(string)$controller; return$this; } /** *Retrievethecurrenterrorhandlercontroller * *@returnstring */ publicfunctiongetErrorHandlerController() { return$this->_errorController; } /** *Settheactionnamefortheerrorhandler * *@paramstring$action *@returnZend_Controller_Plugin_ErrorHandler */ publicfunctionsetErrorHandlerAction($action) { $this->_errorAction=(string)$action; return$this; } /** *Retrievethecurrenterrorhandleraction * *@returnstring */ publicfunctiongetErrorHandlerAction() { return$this->_errorAction; } /** *Routeshutdownhook--Ccheckforrouterexceptions * *@paramZend_Controller_Request_Abstract$request */ publicfunctionrouteShutdown(Zend_Controller_Request_Abstract$request) { $this->_handleError($request); } /** *Predispatchhook--checkforexceptionsanddispatcherrorhandlerif *necessary * *@paramZend_Controller_Request_Abstract$request */ publicfunctionpreDispatch(Zend_Controller_Request_Abstract$request) { $this->_handleError($request); } /** *Postdispatchhook--checkforexceptionsanddispatcherrorhandlerif *necessary * *@paramZend_Controller_Request_Abstract$request */ publicfunctionpostDispatch(Zend_Controller_Request_Abstract$request) { $this->_handleError($request); } /** *Handleerrorsandexceptions * *Ifthe'noErrorHandler'frontcontrollerflaghasbeenset, *returnsearly. * *@paramZend_Controller_Request_Abstract$request *@returnvoid */ protectedfunction_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){ //Exceptionthrownbyerrorhandler;tellthefrontcontrollertothrowit $frontController->throwExceptions(true); throwarray_pop($exceptions); } } //checkforanexceptionANDallowtheerrorhandlercontrollertheoptiontoforward if(($response->isException())&&(!$this->_isInsideErrorHandlerLoop)){ $this->_isInsideErrorHandlerLoop=true; //Getexceptioninformation $error=newArrayObject(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; } //Keepacopyoftheoriginalrequest $error->request=clone$request; //getacountofthenumberofexceptionsencountered $this->_exceptionCountAtFirstEncounter=count($exceptions); //Forwardtotheerrorhandler $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'; classZend_Controller_Plugin_PutHandlerextendsZend_Controller_Plugin_Abstract { /** *Beforedispatching,digestPUTrequestbodyandsetparams * *@paramZend_Controller_Request_Abstract$request */ publicfunctionpreDispatch(Zend_Controller_Request_Abstract$request) { if(!$requestinstanceofZend_Controller_Request_Http){ return; } if($this->_request->isPut()){ $putParams=array(); parse_str($this->_request->getRawBody(),$putParams); $request->setParams($putParams); } } }
更多关于zend相关内容感兴趣的读者可查看本站专题:《ZendFrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。