Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解
本文实例讲述了ZendFramework教程之分发器Zend_Controller_Dispatcher用法。分享给大家供大家参考,具体如下:
分发器的具体实现
ZendFramework的分发器Zend_Controller_Dispatcher设计主要有,如下类和接口组成:
├──Dispatcher
│ ├──Abstract.php
│ ├──Exception.php
│ ├──Interface.php
│ └──Standard.php
Zend_Controller_Dispatcher_Interface
定义了分发器提供的基本和标准功能。
interfaceZend_Controller_Dispatcher_Interface
{
publicfunctionformatControllerName($unformatted);
publicfunctionformatModuleName($unformatted);
publicfunctionformatActionName($unformatted);
publicfunctionisDispatchable(Zend_Controller_Request_Abstract$request);
publicfunctionsetParam($name,$value);
publicfunctionsetParams(array$params);
publicfunctiongetParam($name);
publicfunctiongetParams();
publicfunctionclearParams($name=null);
publicfunctionsetResponse(Zend_Controller_Response_Abstract$response=null);
publicfunctiongetResponse();
publicfunctionaddControllerDirectory($path,$args=null);
publicfunctionsetControllerDirectory($path);
publicfunctiongetControllerDirectory();
publicfunctiondispatch(Zend_Controller_Request_Abstract$request,Zend_Controller_Response_Abstract$response);
publicfunctionisValidModule($module);
publicfunctiongetDefaultModule();
publicfunctiongetDefaultControllerName();
publicfunctiongetDefaultAction();
}
Zend_Controller_Dispatcher_Abstract
实现了Zend_Controller_Dispatcher_Interface接口,提供了分发器提供的基本和标准功能的抽象父类。
<?php
/**Zend_Controller_Dispatcher_Interface*/
require_once'Zend/Controller/Dispatcher/Interface.php';
abstractclassZend_Controller_Dispatcher_AbstractimplementsZend_Controller_Dispatcher_Interface
{
protected$_defaultAction='index';
protected$_defaultController='index';
protected$_defaultModule='default';
protected$_frontController;
protected$_invokeParams=array();
protected$_pathDelimiter='_';
protected$_response=null;
protected$_wordDelimiter=array('-','.');
publicfunction__construct(array$params=array())
{
$this->setParams($params);
}
publicfunctionformatControllerName($unformatted)
{
returnucfirst($this->_formatName($unformatted)).'Controller';
}
publicfunctionformatActionName($unformatted)
{
$formatted=$this->_formatName($unformatted,true);
returnstrtolower(substr($formatted,0,1)).substr($formatted,1).'Action';
}
publicfunction_verifyDelimiter($spec)
{
if(is_string($spec)){
return(array)$spec;
}elseif(is_array($spec)){
$allStrings=true;
foreach($specas$delim){
if(!is_string($delim)){
$allStrings=false;
break;
}
}
if(!$allStrings){
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception('Worddelimiterarraymustcontainonlystrings');
}
return$spec;
}
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception('Invalidworddelimiter');
}
publicfunctiongetWordDelimiter()
{
return$this->_wordDelimiter;
}
publicfunctionsetWordDelimiter($spec)
{
$spec=$this->_verifyDelimiter($spec);
$this->_wordDelimiter=$spec;
return$this;
}
publicfunctiongetPathDelimiter()
{
return$this->_pathDelimiter;
}
publicfunctionsetPathDelimiter($spec)
{
if(!is_string($spec)){
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception('Invalidpathdelimiter');
}
$this->_pathDelimiter=$spec;
return$this;
}
protectedfunction_formatName($unformatted,$isAction=false)
{
//preservedirectories
if(!$isAction){
$segments=explode($this->getPathDelimiter(),$unformatted);
}else{
$segments=(array)$unformatted;
}
foreach($segmentsas$key=>$segment){
$segment=str_replace($this->getWordDelimiter(),'',strtolower($segment));
$segment=preg_replace('/[^a-z0-9]/','',$segment);
$segments[$key]=str_replace('','',ucwords($segment));
}
returnimplode('_',$segments);
}
publicfunctiongetFrontController()
{
if(null===$this->_frontController){
require_once'Zend/Controller/Front.php';
$this->_frontController=Zend_Controller_Front::getInstance();
}
return$this->_frontController;
}
publicfunctionsetFrontController(Zend_Controller_Front$controller)
{
$this->_frontController=$controller;
return$this;
}
publicfunctionsetParam($name,$value)
{
$name=(string)$name;
$this->_invokeParams[$name]=$value;
return$this;
}
publicfunctionsetParams(array$params)
{
$this->_invokeParams=array_merge($this->_invokeParams,$params);
return$this;
}
publicfunctiongetParam($name)
{
if(isset($this->_invokeParams[$name])){
return$this->_invokeParams[$name];
}
returnnull;
}
publicfunctiongetParams()
{
return$this->_invokeParams;
}
publicfunctionclearParams($name=null)
{
if(null===$name){
$this->_invokeParams=array();
}elseif(is_string($name)&&isset($this->_invokeParams[$name])){
unset($this->_invokeParams[$name]);
}elseif(is_array($name)){
foreach($nameas$key){
if(is_string($key)&&isset($this->_invokeParams[$key])){
unset($this->_invokeParams[$key]);
}
}
}
return$this;
}
publicfunctionsetResponse(Zend_Controller_Response_Abstract$response=null)
{
$this->_response=$response;
return$this;
}
publicfunctiongetResponse()
{
return$this->_response;
}
publicfunctionsetDefaultControllerName($controller)
{
$this->_defaultController=(string)$controller;
return$this;
}
publicfunctiongetDefaultControllerName()
{
return$this->_defaultController;
}
publicfunctionsetDefaultAction($action)
{
$this->_defaultAction=(string)$action;
return$this;
}
publicfunctiongetDefaultAction()
{
return$this->_defaultAction;
}
publicfunctionsetDefaultModule($module)
{
$this->_defaultModule=(string)$module;
return$this;
}
publicfunctiongetDefaultModule()
{
return$this->_defaultModule;
}
}
Zend_Controller_Dispatcher_Standard
ZendFramework继承抽象类Zend_Controller_Dispatcher_Abstract,定义了Zend_Controller_Dispatcher_Standard。Zend_Controller_Dispatcher_Standard是ZendFramework提供的基本的分发器,完成了分发功能。
<?php
/**Zend_Loader*/
require_once'Zend/Loader.php';
/**Zend_Controller_Dispatcher_Abstract*/
require_once'Zend/Controller/Dispatcher/Abstract.php';
classZend_Controller_Dispatcher_StandardextendsZend_Controller_Dispatcher_Abstract
{
protected$_curDirectory;
protected$_curModule;
protected$_controllerDirectory=array();
publicfunction__construct(array$params=array())
{
parent::__construct($params);
$this->_curModule=$this->getDefaultModule();
}
publicfunctionaddControllerDirectory($path,$module=null)
{
if(null===$module){
$module=$this->_defaultModule;
}
$module=(string)$module;
$path=rtrim((string)$path,'/\\');
$this->_controllerDirectory[$module]=$path;
return$this;
}
publicfunctionsetControllerDirectory($directory,$module=null)
{
$this->_controllerDirectory=array();
if(is_string($directory)){
$this->addControllerDirectory($directory,$module);
}elseif(is_array($directory)){
foreach((array)$directoryas$module=>$path){
$this->addControllerDirectory($path,$module);
}
}else{
require_once'Zend/Controller/Exception.php';
thrownewZend_Controller_Exception('Controllerdirectoryspecmustbeeitherastringoranarray');
}
return$this;
}
publicfunctiongetControllerDirectory($module=null)
{
if(null===$module){
return$this->_controllerDirectory;
}
$module=(string)$module;
if(array_key_exists($module,$this->_controllerDirectory)){
return$this->_controllerDirectory[$module];
}
returnnull;
}
publicfunctionremoveControllerDirectory($module)
{
$module=(string)$module;
if(array_key_exists($module,$this->_controllerDirectory)){
unset($this->_controllerDirectory[$module]);
returntrue;
}
returnfalse;
}
publicfunctionformatModuleName($unformatted)
{
if(($this->_defaultModule==$unformatted)&&!$this->getParam('prefixDefaultModule')){
return$unformatted;
}
returnucfirst($this->_formatName($unformatted));
}
publicfunctionformatClassName($moduleName,$className)
{
return$this->formatModuleName($moduleName).'_'.$className;
}
publicfunctionclassToFilename($class)
{
returnstr_replace('_',DIRECTORY_SEPARATOR,$class).'.php';
}
publicfunctionisDispatchable(Zend_Controller_Request_Abstract$request)
{
$className=$this->getControllerClass($request);
if(!$className){
returnfalse;
}
$finalClass=$className;
if(($this->_defaultModule!=$this->_curModule)
||$this->getParam('prefixDefaultModule'))
{
$finalClass=$this->formatClassName($this->_curModule,$className);
}
if(class_exists($finalClass,false)){
returntrue;
}
$fileSpec=$this->classToFilename($className);
$dispatchDir=$this->getDispatchDirectory();
$test=$dispatchDir.DIRECTORY_SEPARATOR.$fileSpec;
returnZend_Loader::isReadable($test);
}
publicfunctiondispatch(Zend_Controller_Request_Abstract$request,Zend_Controller_Response_Abstract$response)
{
$this->setResponse($response);
/**
*Getcontrollerclass
*/
if(!$this->isDispatchable($request)){
$controller=$request->getControllerName();
if(!$this->getParam('useDefaultControllerAlways')&&!empty($controller)){
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception('Invalidcontrollerspecified('.$request->getControllerName().')');
}
$className=$this->getDefaultControllerClass($request);
}else{
$className=$this->getControllerClass($request);
if(!$className){
$className=$this->getDefaultControllerClass($request);
}
}
/**
*Loadthecontrollerclassfile
*/
$className=$this->loadClass($className);
/**
*Instantiatecontrollerwithrequest,response,andinvocation
*arguments;throwexceptionifit'snotanactioncontroller
*/
$controller=new$className($request,$this->getResponse(),$this->getParams());
if(!($controllerinstanceofZend_Controller_Action_Interface)&&
!($controllerinstanceofZend_Controller_Action)){
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception(
'Controller"'.$className.'"isnotaninstanceofZend_Controller_Action_Interface'
);
}
/**
*Retrievetheactionname
*/
$action=$this->getActionMethod($request);
/**
*Dispatchthemethodcall
*/
$request->setDispatched(true);
//bydefault,bufferoutput
$disableOb=$this->getParam('disableOutputBuffering');
$obLevel=ob_get_level();
if(empty($disableOb)){
ob_start();
}
try{
$controller->dispatch($action);
}catch(Exception$e){
//Cleanoutputbufferonerror
$curObLevel=ob_get_level();
if($curObLevel>$obLevel){
do{
ob_get_clean();
$curObLevel=ob_get_level();
}while($curObLevel>$obLevel);
}
throw$e;
}
if(empty($disableOb)){
$content=ob_get_clean();
$response->appendBody($content);
}
//Destroythepagecontrollerinstanceandreflectionobjects
$controller=null;
}
publicfunctionloadClass($className)
{
$finalClass=$className;
if(($this->_defaultModule!=$this->_curModule)
||$this->getParam('prefixDefaultModule'))
{
$finalClass=$this->formatClassName($this->_curModule,$className);
}
if(class_exists($finalClass,false)){
return$finalClass;
}
$dispatchDir=$this->getDispatchDirectory();
$loadFile=$dispatchDir.DIRECTORY_SEPARATOR.$this->classToFilename($className);
if(Zend_Loader::isReadable($loadFile)){
include_once$loadFile;
}else{
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception('Cannotloadcontrollerclass"'.$className.'"fromfile"'.$loadFile."'");
}
if(!class_exists($finalClass,false)){
require_once'Zend/Controller/Dispatcher/Exception.php';
thrownewZend_Controller_Dispatcher_Exception('Invalidcontrollerclass("'.$finalClass.'")');
}
return$finalClass;
}
publicfunctiongetControllerClass(Zend_Controller_Request_Abstract$request)
{
$controllerName=$request->getControllerName();
if(empty($controllerName)){
if(!$this->getParam('useDefaultControllerAlways')){
returnfalse;
}
$controllerName=$this->getDefaultControllerName();
$request->setControllerName($controllerName);
}
$className=$this->formatControllerName($controllerName);
$controllerDirs=$this->getControllerDirectory();
$module=$request->getModuleName();
if($this->isValidModule($module)){
$this->_curModule=$module;
$this->_curDirectory=$controllerDirs[$module];
}elseif($this->isValidModule($this->_defaultModule)){
$request->setModuleName($this->_defaultModule);
$this->_curModule=$this->_defaultModule;
$this->_curDirectory=$controllerDirs[$this->_defaultModule];
}else{
require_once'Zend/Controller/Exception.php';
thrownewZend_Controller_Exception('Nodefaultmoduledefinedforthisapplication');
}
return$className;
}
publicfunctionisValidModule($module)
{
if(!is_string($module)){
returnfalse;
}
$module=strtolower($module);
$controllerDir=$this->getControllerDirectory();
foreach(array_keys($controllerDir)as$moduleName){
if($module==strtolower($moduleName)){
returntrue;
}
}
returnfalse;
}
publicfunctiongetDefaultControllerClass(Zend_Controller_Request_Abstract$request)
{
$controller=$this->getDefaultControllerName();
$default=$this->formatControllerName($controller);
$request->setControllerName($controller)
->setActionName(null);
$module=$request->getModuleName();
$controllerDirs=$this->getControllerDirectory();
$this->_curModule=$this->_defaultModule;
$this->_curDirectory=$controllerDirs[$this->_defaultModule];
if($this->isValidModule($module)){
$found=false;
if(class_exists($default,false)){
$found=true;
}else{
$moduleDir=$controllerDirs[$module];
$fileSpec=$moduleDir.DIRECTORY_SEPARATOR.$this->classToFilename($default);
if(Zend_Loader::isReadable($fileSpec)){
$found=true;
$this->_curDirectory=$moduleDir;
}
}
if($found){
$request->setModuleName($module);
$this->_curModule=$this->formatModuleName($module);
}
}else{
$request->setModuleName($this->_defaultModule);
}
return$default;
}
publicfunctiongetDispatchDirectory()
{
return$this->_curDirectory;
}
publicfunctiongetActionMethod(Zend_Controller_Request_Abstract$request)
{
$action=$request->getActionName();
if(empty($action)){
$action=$this->getDefaultAction();
$request->setActionName($action);
}
return$this->formatActionName($action);
}
}
前端控制器和分发器
<?php
/**Zend_Loader*/
require_once'Zend/Loader.php';
/**Zend_Controller_Action_HelperBroker*/
require_once'Zend/Controller/Action/HelperBroker.php';
/**Zend_Controller_Plugin_Broker*/
require_once'Zend/Controller/Plugin/Broker.php';
classZend_Controller_Front
{
protected$_baseUrl=null;
protected$_controllerDir=null;
protected$_dispatcher=null;
protectedstatic$_instance=null;
protected$_invokeParams=array();
protected$_moduleControllerDirectoryName='controllers';
protected$_plugins=null;
protected$_request=null;
protected$_response=null;
protected$_returnResponse=false;
protected$_router=null;
protected$_throwExceptions=false;
protectedfunction__construct()
{
$this->_plugins=newZend_Controller_Plugin_Broker();
}
privatefunction__clone()
{
}
publicstaticfunctiongetInstance()
{
if(null===self::$_instance){
self::$_instance=newself();
}
returnself::$_instance;
}
publicfunctionresetInstance()
{
$reflection=newReflectionObject($this);
foreach($reflection->getProperties()as$property){
$name=$property->getName();
switch($name){
case'_instance':
break;
case'_controllerDir':
case'_invokeParams':
$this->{$name}=array();
break;
case'_plugins':
$this->{$name}=newZend_Controller_Plugin_Broker();
break;
case'_throwExceptions':
case'_returnResponse':
$this->{$name}=false;
break;
case'_moduleControllerDirectoryName':
$this->{$name}='controllers';
break;
default:
$this->{$name}=null;
break;
}
}
Zend_Controller_Action_HelperBroker::resetHelpers();
}
publicstaticfunctionrun($controllerDirectory)
{
self::getInstance()
->setControllerDirectory($controllerDirectory)
->dispatch();
}
publicfunctionaddControllerDirectory($directory,$module=null)
{
$this->getDispatcher()->addControllerDirectory($directory,$module);
return$this;
}
publicfunctionsetControllerDirectory($directory,$module=null)
{
$this->getDispatcher()->setControllerDirectory($directory,$module);
return$this;
}
publicfunctiongetControllerDirectory($name=null)
{
return$this->getDispatcher()->getControllerDirectory($name);
}
publicfunctionremoveControllerDirectory($module)
{
return$this->getDispatcher()->removeControllerDirectory($module);
}
publicfunctionaddModuleDirectory($path)
{
try{
$dir=newDirectoryIterator($path);
}catch(Exception$e){
require_once'Zend/Controller/Exception.php';
thrownewZend_Controller_Exception("Directory$pathnotreadable",0,$e);
}
foreach($diras$file){
if($file->isDot()||!$file->isDir()){
continue;
}
$module=$file->getFilename();
//Don'tuseSCCSdirectoriesasmodules
if(preg_match('/^[^a-z]/i',$module)||('CVS'==$module)){
continue;
}
$moduleDir=$file->getPathname().DIRECTORY_SEPARATOR.$this->getModuleControllerDirectoryName();
$this->addControllerDirectory($moduleDir,$module);
}
return$this;
}
publicfunctiongetModuleDirectory($module=null)
{
if(null===$module){
$request=$this->getRequest();
if(null!==$request){
$module=$this->getRequest()->getModuleName();
}
if(empty($module)){
$module=$this->getDispatcher()->getDefaultModule();
}
}
$controllerDir=$this->getControllerDirectory($module);
if((null===$controllerDir)||!is_string($controllerDir)){
returnnull;
}
returndirname($controllerDir);
}
publicfunctionsetModuleControllerDirectoryName($name='controllers')
{
$this->_moduleControllerDirectoryName=(string)$name;
return$this;
}
publicfunctiongetModuleControllerDirectoryName()
{
return$this->_moduleControllerDirectoryName;
}
publicfunctionsetDefaultControllerName($controller)
{
$dispatcher=$this->getDispatcher();
$dispatcher->setDefaultControllerName($controller);
return$this;
}
publicfunctiongetDefaultControllerName()
{
return$this->getDispatcher()->getDefaultControllerName();
}
publicfunctionsetDefaultAction($action)
{
$dispatcher=$this->getDispatcher();
$dispatcher->setDefaultAction($action);
return$this;
}
publicfunctiongetDefaultAction()
{
return$this->getDispatcher()->getDefaultAction();
}
publicfunctionsetDefaultModule($module)
{
$dispatcher=$this->getDispatcher();
$dispatcher->setDefaultModule($module);
return$this;
}
publicfunctiongetDefaultModule()
{
return$this->getDispatcher()->getDefaultModule();
}
publicfunctionsetRequest($request)
{
...........................
return$this;
}
publicfunctiongetRequest()
{
return$this->_request;
}
publicfunctionsetRouter($router)
{
....................
return$this;
}
publicfunctiongetRouter()
{
..................
return$this->_router;
}
publicfunctionsetBaseUrl($base=null)
{
..............
return$this;
}
publicfunctiongetBaseUrl()
{
return$this->_baseUrl;
}
/**
*Setthedispatcherobject.Thedispatcherisresponsiblefor
*takingaZend_Controller_Dispatcher_Tokenobject,instantiatingthecontroller,and
*calltheactionmethodofthecontroller.
*
*@paramZend_Controller_Dispatcher_Interface$dispatcher
*@returnZend_Controller_Front
*/
publicfunctionsetDispatcher(Zend_Controller_Dispatcher_Interface$dispatcher)
{
$this->_dispatcher=$dispatcher;
return$this;
}
/**
*Returnthedispatcherobject.
*
*@returnZend_Controller_Dispatcher_Interface
*/
publicfunctiongetDispatcher()
{
/**
*Instantiatethedefaultdispatcherifonewasnotset.
*/
if(!$this->_dispatcherinstanceofZend_Controller_Dispatcher_Interface){
require_once'Zend/Controller/Dispatcher/Standard.php';
$this->_dispatcher=newZend_Controller_Dispatcher_Standard();
}
return$this->_dispatcher;
}
publicfunctionsetResponse($response)
{..................
return$this;
}
publicfunctiongetResponse()
{
return$this->_response;
}
publicfunctionsetParam($name,$value)
{
$name=(string)$name;
$this->_invokeParams[$name]=$value;
return$this;
}
publicfunctionsetParams(array$params)
{
$this->_invokeParams=array_merge($this->_invokeParams,$params);
return$this;
}
publicfunctiongetParam($name)
{
if(isset($this->_invokeParams[$name])){
return$this->_invokeParams[$name];
}
returnnull;
}
publicfunctiongetParams()
{
return$this->_invokeParams;
}
publicfunctionclearParams($name=null)
{
if(null===$name){
$this->_invokeParams=array();
}elseif(is_string($name)&&isset($this->_invokeParams[$name])){
unset($this->_invokeParams[$name]);
}elseif(is_array($name)){
foreach($nameas$key){
if(is_string($key)&&isset($this->_invokeParams[$key])){
unset($this->_invokeParams[$key]);
}
}
}
return$this;
}
publicfunctionregisterPlugin(Zend_Controller_Plugin_Abstract$plugin,$stackIndex=null)
{
$this->_plugins->registerPlugin($plugin,$stackIndex);
return$this;
}
publicfunctionunregisterPlugin($plugin)
{
$this->_plugins->unregisterPlugin($plugin);
return$this;
}
publicfunctionhasPlugin($class)
{
return$this->_plugins->hasPlugin($class);
}
publicfunctiongetPlugin($class)
{
return$this->_plugins->getPlugin($class);
}
publicfunctiongetPlugins()
{
return$this->_plugins->getPlugins();
}
publicfunctionthrowExceptions($flag=null)
{
.....................
return$this->_throwExceptions;
}
publicfunctionreturnResponse($flag=null)
{
................
return$this->_returnResponse;
}
/**
*DispatchanHTTPrequesttoacontroller/action.
*
*@paramZend_Controller_Request_Abstract|null$request
*@paramZend_Controller_Response_Abstract|null$response
*@returnvoid|Zend_Controller_Response_AbstractReturnsresponseobjectifreturnResponse()istrue
*/
publicfunctiondispatch(Zend_Controller_Request_Abstract$request=null,Zend_Controller_Response_Abstract$response=null)
{
if(!$this->getParam('noErrorHandler')&&!$this->_plugins->hasPlugin('Zend_Controller_Plugin_ErrorHandler')){
//Registerwithstackindexof100
require_once'Zend/Controller/Plugin/ErrorHandler.php';
$this->_plugins->registerPlugin(newZend_Controller_Plugin_ErrorHandler(),100);
}
if(!$this->getParam('noViewRenderer')&&!Zend_Controller_Action_HelperBroker::hasHelper('viewRenderer')){
require_once'Zend/Controller/Action/Helper/ViewRenderer.php';
Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-80,newZend_Controller_Action_Helper_ViewRenderer());
}
/**
*Instantiatedefaultrequestobject(HTTPversion)ifnoneprovided
*/
if(null!==$request){
$this->setRequest($request);
}elseif((null===$request)&&(null===($request=$this->getRequest()))){
require_once'Zend/Controller/Request/Http.php';
$request=newZend_Controller_Request_Http();
$this->setRequest($request);
}
/**
*SetbaseURLofrequestobject,ifavailable
*/
if(is_callable(array($this->_request,'setBaseUrl'))){
if(null!==$this->_baseUrl){
$this->_request->setBaseUrl($this->_baseUrl);
}
}
/**
*Instantiatedefaultresponseobject(HTTPversion)ifnoneprovided
*/
if(null!==$response){
$this->setResponse($response);
}elseif((null===$this->_response)&&(null===($this->_response=$this->getResponse()))){
require_once'Zend/Controller/Response/Http.php';
$response=newZend_Controller_Response_Http();
$this->setResponse($response);
}
/**
*Registerrequestandresponseobjectswithpluginbroker
*/
$this->_plugins
->setRequest($this->_request)
->setResponse($this->_response);
/**
*Initializerouter
*/
$router=$this->getRouter();
$router->setParams($this->getParams());
/**
*Initializedispatcher
*/
$dispatcher=$this->getDispatcher();
$dispatcher->setParams($this->getParams())
->setResponse($this->_response);
//Begindispatch
try{
/**
*Routerequesttocontroller/action,ifarouterisprovided
*/
/**
*Notifypluginsofrouterstartup
*/
$this->_plugins->routeStartup($this->_request);
try{
$router->route($this->_request);
}catch(Exception$e){
if($this->throwExceptions()){
throw$e;
}
$this->_response->setException($e);
}
/**
*Notifypluginsofroutercompletion
*/
$this->_plugins->routeShutdown($this->_request);
/**
*Notifypluginsofdispatchloopstartup
*/
$this->_plugins->dispatchLoopStartup($this->_request);
/**
*Attempttodispatchthecontroller/action.Ifthe$this->_request
*indicatesthatitneedstobedispatched,movetothenext
*actionintherequest.
*/
do{
$this->_request->setDispatched(true);
/**
*Notifypluginsofdispatchstartup
*/
$this->_plugins->preDispatch($this->_request);
/**
*SkiprequestedactionifpreDispatch()hasresetit
*/
if(!$this->_request->isDispatched()){
continue;
}
/**
*Dispatchrequest
*/
try{
$dispatcher->dispatch($this->_request,$this->_response);
}catch(Exception$e){
if($this->throwExceptions()){
throw$e;
}
$this->_response->setException($e);
}
/**
*Notifypluginsofdispatchcompletion
*/
$this->_plugins->postDispatch($this->_request);
}while(!$this->_request->isDispatched());
}catch(Exception$e){
if($this->throwExceptions()){
throw$e;
}
$this->_response->setException($e);
}
/**
*Notifypluginsofdispatchloopcompletion
*/
try{
$this->_plugins->dispatchLoopShutdown();
}catch(Exception$e){
if($this->throwExceptions()){
throw$e;
}
$this->_response->setException($e);
}
if($this->returnResponse()){
return$this->_response;
}
$this->_response->sendResponse();
}
}
以上对Zend_Controller_Front和Zend_Controller_Dispatcher做了简单的标记,通过分析代码不难看出,基本的运行机制。
分发发生在前端控制器中的一个循环(loop)中。分发之前,前端控制器通过路由请求,找到用户指定的模块、控制器、动作和可选参数。然后进入分发循环,分发请求。
分发器需要大量数据完成任务——它需要知道如何格式化控制器和动作的名称,到哪儿找到控制器类文件,模块名是否有效,以及基于其它可用信息判定请求是否能分发的API。
每次迭代(iteration)过程开始时,在请求对象中设置一个标志指示该动作已分发。如果在动作或者前/后分发(pre/postDispatch)插件重置了该标志,分发循环将继续下去并试图分发新的请求。通过改变请求中的控制器或者动作并重置已分发标志,开发人员可以定制执行一个请求链。
控制这种分发过程的动作控制器方法是_forward();在任意的pre/postDispatch()或者动作中调用该方法,并传入动作、控制器、模块、以及可选的附加参数,就可以进入新的动作。
自定义分发器
Zend_Controller_Dispatcher_Interface定义了下列所有分发器需要实现的方法。
不过大多数情况下,只需要简单地扩展抽象类Zend_Controller_Dispatcher_Abstract,其中已经定义好了上面的大部分方法。或者扩展Zend_Controller_Dispatcher_Standard类,基于标准分发器来修改功能。
需要子类化分发器的可能原因包括:期望在动作控制器中使用不同的类和方法命名模式,或者期望使用不同的分发方式,比如分发到控制器目录下的动作文件,而不是控制器类的动作方法。
更多关于zend相关内容感兴趣的读者可查看本站专题:《ZendFrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。