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程序设计有所帮助。