当前位置:首页 > CMS教程 > 其它CMS > 列表

Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解

发布:smiling 来源: PHP粉丝网  添加日期:2021-07-13 15:39:58 浏览: 评论:0 

这篇文章主要介绍了Zend Framework教程之分发器Zend_Controller_Dispatcher用法,结合实例形式详细分析了分发器Zend_Controller_Dispatcher的结构,功能,使用技巧与相关注意事项,需要的朋友可以参考下。

本文实例讲述了Zend Framework教程之分发器Zend_Controller_Dispatcher用法,分享给大家供大家参考,具体如下:

分发器的具体实现

Zend Framework的分发器Zend_Controller_Dispatcher设计主要有,如下类和接口组成:

  1. ├── Dispatcher 
  2. │   ├── Abstract.php 
  3. │   ├── Exception.php 
  4. │   ├── Interface.php 
  5. │   └── Standard.php 

Zend_Controller_Dispatcher_Interface

定义了分发器提供的基本和标准功能。

  1. interface Zend_Controller_Dispatcher_Interface 
  2.   public function formatControllerName($unformatted); 
  3.   public function formatModuleName($unformatted); 
  4.   public function formatActionName($unformatted); 
  5.   public function isDispatchable(Zend_Controller_Request_Abstract $request); 
  6.   public function setParam($name$value); 
  7.   public function setParams(array $params); 
  8.   public function getParam($name); 
  9.   public function getParams(); 
  10.   public function clearParams($name = null); 
  11.   public function setResponse(Zend_Controller_Response_Abstract $response = null); 
  12.   public function getResponse(); 
  13.   public function addControllerDirectory($path$args = null); 
  14.   public function setControllerDirectory($path); 
  15.   public function getControllerDirectory(); 
  16.   public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response); 
  17.   public function isValidModule($module); 
  18.   public function getDefaultModule(); 
  19.   public function getDefaultControllerName(); 
  20.   public function getDefaultAction(); 

Zend_Controller_Dispatcher_Abstract

实现了Zend_Controller_Dispatcher_Interface接口,提供了分发器提供的基本和标准功能的抽象父类。

  1. <?php 
  2. /** Zend_Controller_Dispatcher_Interface */ 
  3. require_once 'Zend/Controller/Dispatcher/Interface.php'
  4. abstract class Zend_Controller_Dispatcher_Abstract implements Zend_Controller_Dispatcher_Interface 
  5.   protected $_defaultAction = 'index'
  6.   protected $_defaultController = 'index'
  7.   protected $_defaultModule = 'default'
  8.   protected $_frontController
  9.   protected $_invokeParams = array(); 
  10.   protected $_pathDelimiter = '_'
  11.   protected $_response = null; 
  12.   protected $_wordDelimiter = array('-''.'); 
  13.   public function __construct(array $params = array()) 
  14.   { 
  15.     $this->setParams($params); 
  16.   } 
  17.   public function formatControllerName($unformatted
  18.   { 
  19.     return ucfirst($this->_formatName($unformatted)) . 'Controller'
  20.   } 
  21.   public function formatActionName($unformatted
  22.   { 
  23.     $formatted = $this->_formatName($unformatted, true); 
  24.     return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1) . 'Action'
  25.   } 
  26.   public function _verifyDelimiter($spec
  27.   { 
  28.     if (is_string($spec)) { 
  29.       return (array$spec
  30.     } elseif (is_array($spec)) { 
  31.       $allStrings = true; 
  32.       foreach ($spec as $delim) { 
  33.         if (!is_string($delim)) { 
  34.           $allStrings = false; 
  35.           break
  36.         } 
  37.       } 
  38.       if (!$allStrings) { 
  39.         require_once 'Zend/Controller/Dispatcher/Exception.php'
  40.         throw new Zend_Controller_Dispatcher_Exception('Word delimiter array must contain only strings'); 
  41.       } 
  42.       return $spec
  43.     } 
  44.     require_once 'Zend/Controller/Dispatcher/Exception.php'
  45.     throw new Zend_Controller_Dispatcher_Exception('Invalid word delimiter'); 
  46.   } 
  47.   public function getWordDelimiter() 
  48.   { 
  49.     return $this->_wordDelimiter; 
  50.   } 
  51.   public function setWordDelimiter($spec
  52.   { 
  53.     $spec = $this->_verifyDelimiter($spec); 
  54.     $this->_wordDelimiter = $spec
  55.     return $this
  56.   } 
  57.   public function getPathDelimiter() 
  58.   { 
  59.     return $this->_pathDelimiter; 
  60.   } 
  61.   public function setPathDelimiter($spec
  62.   { 
  63.     if (!is_string($spec)) { 
  64.       require_once 'Zend/Controller/Dispatcher/Exception.php'
  65.       throw new Zend_Controller_Dispatcher_Exception('Invalid path delimiter'); 
  66.     } 
  67.     $this->_pathDelimiter = $spec
  68.     return $this
  69.   } 
  70.   protected function _formatName($unformatted$isAction = false) 
  71.   { 
  72.     // preserve directories 
  73.     if (!$isAction) { 
  74.       $segments = explode($this->getPathDelimiter(), $unformatted); 
  75.     } else { 
  76.       $segments = (array$unformatted
  77.     } 
  78.     foreach ($segments as $key => $segment) { 
  79.       $segment    = str_replace($this->getWordDelimiter(), ' 'strtolower($segment)); 
  80.       $segment    = preg_replace('/[^a-z0-9 ]/'''$segment); 
  81.       $segments[$key] = str_replace(' ''', ucwords($segment)); 
  82.     } 
  83.     return implode('_'$segments); 
  84.   } 
  85.   public function getFrontController() 
  86.   { 
  87.     if (null === $this->_frontController) { 
  88.       require_once 'Zend/Controller/Front.php'
  89.       $this->_frontController = Zend_Controller_Front::getInstance(); 
  90.     } 
  91.     return $this->_frontController; 
  92.   } 
  93.   public function setFrontController(Zend_Controller_Front $controller
  94.   { 
  95.     $this->_frontController = $controller
  96.     return $this
  97.   } 
  98.   public function setParam($name$value
  99.   { 
  100.     $name = (string) $name
  101.     $this->_invokeParams[$name] = $value
  102.     return $this
  103.   } 
  104.   public function setParams(array $params
  105.   { 
  106.     $this->_invokeParams = array_merge($this->_invokeParams, $params); 
  107.     return $this
  108.   } 
  109.   public function getParam($name
  110.   { 
  111.     if(isset($this->_invokeParams[$name])) { 
  112.       return $this->_invokeParams[$name]; 
  113.     } 
  114.     return null; 
  115.   } 
  116.   public function getParams() 
  117.   { 
  118.     return $this->_invokeParams; 
  119.   } 
  120.   public function clearParams($name = null) 
  121.   { 
  122.     if (null === $name) { 
  123.       $this->_invokeParams = array(); 
  124.     } elseif (is_string($name) && isset($this->_invokeParams[$name])) { 
  125.       unset($this->_invokeParams[$name]); 
  126.     } elseif (is_array($name)) { 
  127.       foreach ($name as $key) { 
  128.         if (is_string($key) && isset($this->_invokeParams[$key])) { 
  129.           unset($this->_invokeParams[$key]); 
  130.         } 
  131.       } 
  132.     } 
  133.     return $this
  134.   } 
  135.   public function setResponse(Zend_Controller_Response_Abstract $response = null) 
  136.   { 
  137.     $this->_response = $response
  138.     return $this
  139.   } 
  140.   public function getResponse() 
  141.   { 
  142.     return $this->_response; 
  143.   } 
  144.   public function setDefaultControllerName($controller
  145.   { 
  146.     $this->_defaultController = (string) $controller
  147.     return $this
  148.   } 
  149.   public function getDefaultControllerName() 
  150.   { 
  151.     return $this->_defaultController; 
  152.   } 
  153.   public function setDefaultAction($action
  154.   { 
  155.     $this->_defaultAction = (string) $action
  156.     return $this
  157.   } 
  158.   public function getDefaultAction() 
  159.   { 
  160.     return $this->_defaultAction; 
  161.   } 
  162.   public function setDefaultModule($module
  163.   { 
  164.     $this->_defaultModule = (string) $module
  165.     return $this
  166.   } 
  167.   public function getDefaultModule() 
  168.   { 
  169.     return $this->_defaultModule; 
  170.   } 

Zend_Controller_Dispatcher_Standard

ZendFramework继承抽象类Zend_Controller_Dispatcher_Abstract,定义了Zend_Controller_Dispatcher_Standard。Zend_Controller_Dispatcher_Standard是ZendFramework提供的基本的分发器,完成了分发功能。

  1. <?php 
  2. /** Zend_Loader */ 
  3. require_once 'Zend/Loader.php'
  4. /** Zend_Controller_Dispatcher_Abstract */ 
  5. require_once 'Zend/Controller/Dispatcher/Abstract.php'
  6. class Zend_Controller_Dispatcher_Standard extends Zend_Controller_Dispatcher_Abstract 
  7.   protected $_curDirectory
  8.   protected $_curModule
  9.   protected $_controllerDirectory = array(); 
  10.   public function __construct(array $params = array()) 
  11.   { 
  12.     parent::__construct($params); 
  13.     $this->_curModule = $this->getDefaultModule(); 
  14.   } 
  15.   public function addControllerDirectory($path$module = null) 
  16.   { 
  17.     if (null === $module) { 
  18.       $module = $this->_defaultModule; 
  19.     } 
  20.     $module = (string) $module
  21.     $path  = rtrim((string) $path'/\\'); 
  22.     $this->_controllerDirectory[$module] = $path
  23.     return $this
  24.   } 
  25.   public function setControllerDirectory($directory$module = null) 
  26.   { 
  27.     $this->_controllerDirectory = array(); 
  28.     if (is_string($directory)) { 
  29.       $this->addControllerDirectory($directory$module); 
  30.     } elseif (is_array($directory)) { 
  31.       foreach ((array$directory as $module => $path) { 
  32.         $this->addControllerDirectory($path$module); 
  33.       } 
  34.     } else { 
  35.       require_once 'Zend/Controller/Exception.php'
  36.       throw new Zend_Controller_Exception('Controller directory spec must be either a string or an array'); 
  37.     } 
  38.     return $this
  39.   } 
  40.   public function getControllerDirectory($module = null) 
  41.   { 
  42.     if (null === $module) { 
  43.       return $this->_controllerDirectory; 
  44.     } 
  45.     $module = (string) $module
  46.     if (array_key_exists($module$this->_controllerDirectory)) { 
  47.       return $this->_controllerDirectory[$module]; 
  48.     } 
  49.     return null; 
  50.   } 
  51.   public function removeControllerDirectory($module
  52.   { 
  53.     $module = (string) $module
  54.     if (array_key_exists($module$this->_controllerDirectory)) { 
  55.       unset($this->_controllerDirectory[$module]); 
  56.       return true; 
  57.     } 
  58.     return false; 
  59.   } 
  60.   public function formatModuleName($unformatted
  61.   { 
  62.     if (($this->_defaultModule == $unformatted) && !$this->getParam('prefixDefaultModule')) { 
  63.       return $unformatted
  64.     } 
  65.     return ucfirst($this->_formatName($unformatted)); 
  66.   } 
  67.   public function formatClassName($moduleName$className
  68.   { 
  69.     return $this->formatModuleName($moduleName) . '_' . $className
  70.   } 
  71.   public function classToFilename($class
  72.   { 
  73.     return str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'
  74.   } 
  75.   public function isDispatchable(Zend_Controller_Request_Abstract $request
  76.   { 
  77.     $className = $this->getControllerClass($request); 
  78.     if (!$className) { 
  79.       return false; 
  80.     } 
  81.     $finalClass = $className
  82.     if (($this->_defaultModule != $this->_curModule) 
  83.       || $this->getParam('prefixDefaultModule')) 
  84.     { 
  85.       $finalClass = $this->formatClassName($this->_curModule, $className); 
  86.     } 
  87.     if (class_exists($finalClass, false)) { 
  88.       return true; 
  89.     } 
  90.     $fileSpec  = $this->classToFilename($className); 
  91.     $dispatchDir = $this->getDispatchDirectory(); 
  92.     $test    = $dispatchDir . DIRECTORY_SEPARATOR . $fileSpec
  93.     return Zend_Loader::isReadable($test); 
  94.   } 
  95.   public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response
  96.   { 
  97.     $this->setResponse($response); 
  98.     /** 
  99.      * Get controller class 
  100.      */ 
  101.     if (!$this->isDispatchable($request)) { 
  102.       $controller = $request->getControllerName(); 
  103.       if (!$this->getParam('useDefaultControllerAlways') && !emptyempty($controller)) { 
  104.         require_once 'Zend/Controller/Dispatcher/Exception.php'
  105.         throw new Zend_Controller_Dispatcher_Exception('Invalid controller specified (' . $request->getControllerName() . ')'); 
  106.       } 
  107.       $className = $this->getDefaultControllerClass($request); 
  108.     } else { 
  109.       $className = $this->getControllerClass($request); 
  110.       if (!$className) { 
  111.         $className = $this->getDefaultControllerClass($request); 
  112.       } 
  113.     } 
  114.     /** 
  115.      * Load the controller class file 
  116.      */ 
  117.     $className = $this->loadClass($className); 
  118.     /** 
  119.      * Instantiate controller with request, response, and invocation 
  120.      * arguments; throw exception if it's not an action controller 
  121.      */ 
  122.     $controller = new $className($request$this->getResponse(), $this->getParams()); 
  123.     if (!($controller instanceof Zend_Controller_Action_Interface) && 
  124.       !($controller instanceof Zend_Controller_Action)) { 
  125.       require_once 'Zend/Controller/Dispatcher/Exception.php'
  126.       throw new Zend_Controller_Dispatcher_Exception( 
  127.         'Controller "' . $className . '" is not an instance of Zend_Controller_Action_Interface' 
  128.       ); 
  129.     } 
  130.     /** 
  131.      * Retrieve the action name 
  132.      */ 
  133.     $action = $this->getActionMethod($request); 
  134.     /** 
  135.      * Dispatch the method call 
  136.      */ 
  137.     $request->setDispatched(true); 
  138.     // by default, buffer output 
  139.     $disableOb = $this->getParam('disableOutputBuffering'); 
  140.     $obLevel  = ob_get_level(); 
  141.     if (emptyempty($disableOb)) { 
  142.       ob_start(); 
  143.     } 
  144.     try { 
  145.       $controller->dispatch($action); 
  146.     } catch (Exception $e) { 
  147.       // Clean output buffer on error 
  148.       $curObLevel = ob_get_level(); 
  149.       if ($curObLevel > $obLevel) { 
  150.         do { 
  151.           ob_get_clean(); 
  152.           $curObLevel = ob_get_level(); 
  153.         } while ($curObLevel > $obLevel); 
  154.       } 
  155.       throw $e
  156.     } 
  157.     if (emptyempty($disableOb)) { 
  158.       $content = ob_get_clean(); 
  159.       $response->appendBody($content); 
  160.     } 
  161.     // Destroy the page controller instance and reflection objects 
  162.     $controller = null; 
  163.   } 
  164.   public function loadClass($className
  165.   { 
  166.     $finalClass = $className
  167.     if (($this->_defaultModule != $this->_curModule) 
  168.       || $this->getParam('prefixDefaultModule')) 
  169.     { 
  170.       $finalClass = $this->formatClassName($this->_curModule, $className); 
  171.     } 
  172.     if (class_exists($finalClass, false)) { 
  173.       return $finalClass
  174.     } 
  175.     $dispatchDir = $this->getDispatchDirectory(); 
  176.     $loadFile  = $dispatchDir . DIRECTORY_SEPARATOR . $this->classToFilename($className); 
  177.     if (Zend_Loader::isReadable($loadFile)) { 
  178.       include_once $loadFile
  179.     } else { 
  180.       require_once 'Zend/Controller/Dispatcher/Exception.php'
  181.       throw new Zend_Controller_Dispatcher_Exception('Cannot load controller class "' . $className . '" from file "' . $loadFile . "'"); 
  182.     } 
  183.     if (!class_exists($finalClass, false)) { 
  184.       require_once 'Zend/Controller/Dispatcher/Exception.php'
  185.       throw new Zend_Controller_Dispatcher_Exception('Invalid controller class ("' . $finalClass . '")'); 
  186.     } 
  187.     return $finalClass
  188.   } 
  189.   public function getControllerClass(Zend_Controller_Request_Abstract $request
  190.   { 
  191.     $controllerName = $request->getControllerName(); 
  192.     if (emptyempty($controllerName)) { 
  193.       if (!$this->getParam('useDefaultControllerAlways')) { 
  194.         return false; 
  195.       } 
  196.       $controllerName = $this->getDefaultControllerName(); 
  197.       $request->setControllerName($controllerName); 
  198.     } 
  199.     $className = $this->formatControllerName($controllerName); 
  200.     $controllerDirs   = $this->getControllerDirectory(); 
  201.     $module = $request->getModuleName(); 
  202.     if ($this->isValidModule($module)) { 
  203.       $this->_curModule  = $module
  204.       $this->_curDirectory = $controllerDirs[$module]; 
  205.     } elseif ($this->isValidModule($this->_defaultModule)) { 
  206.       $request->setModuleName($this->_defaultModule); 
  207.       $this->_curModule  = $this->_defaultModule; 
  208.       $this->_curDirectory = $controllerDirs[$this->_defaultModule]; 
  209.     } else { 
  210.       require_once 'Zend/Controller/Exception.php'
  211.       throw new Zend_Controller_Exception('No default module defined for this application'); 
  212.     } 
  213.     return $className
  214.   } 
  215.   public function isValidModule($module
  216.   { 
  217.     if (!is_string($module)) { 
  218.       return false; 
  219.     } 
  220.     $module    = strtolower($module); 
  221.     $controllerDir = $this->getControllerDirectory(); 
  222.     foreach (array_keys($controllerDiras $moduleName) { 
  223.       if ($module == strtolower($moduleName)) { 
  224.         return true; 
  225.       } 
  226.     } 
  227.     return false; 
  228.   } 
  229.   public function getDefaultControllerClass(Zend_Controller_Request_Abstract $request
  230.   { 
  231.     $controller = $this->getDefaultControllerName(); 
  232.     $default  = $this->formatControllerName($controller); 
  233.     $request->setControllerName($controller
  234.         ->setActionName(null); 
  235.     $module       = $request->getModuleName(); 
  236.     $controllerDirs   = $this->getControllerDirectory(); 
  237.     $this->_curModule  = $this->_defaultModule; 
  238.     $this->_curDirectory = $controllerDirs[$this->_defaultModule]; 
  239.     if ($this->isValidModule($module)) { 
  240.       $found = false; 
  241.       if (class_exists($default, false)) { 
  242.         $found = true; 
  243.       } else { 
  244.         $moduleDir = $controllerDirs[$module]; 
  245.         $fileSpec = $moduleDir . DIRECTORY_SEPARATOR . $this->classToFilename($default); 
  246.         if (Zend_Loader::isReadable($fileSpec)) { 
  247.           $found = true; 
  248.           $this->_curDirectory = $moduleDir
  249.         } 
  250.       } 
  251.       if ($found) { 
  252.         $request->setModuleName($module); 
  253.         $this->_curModule  = $this->formatModuleName($module); 
  254.       } 
  255.     } else { 
  256.       $request->setModuleName($this->_defaultModule); 
  257.     } 
  258.     return $default
  259.   } 
  260.   public function getDispatchDirectory() 
  261.   { 
  262.     return $this->_curDirectory; 
  263.   } 
  264.   public function getActionMethod(Zend_Controller_Request_Abstract $request
  265.   { 
  266.     $action = $request->getActionName(); 
  267.     if (emptyempty($action)) { 
  268.       $action = $this->getDefaultAction(); 
  269.       $request->setActionName($action); 
  270.     } 
  271.     return $this->formatActionName($action); 
  272.   } 

前端控制器和分发器

  1. <?php 
  2. /** Zend_Loader */ 
  3. require_once 'Zend/Loader.php'
  4. /** Zend_Controller_Action_HelperBroker */ 
  5. require_once 'Zend/Controller/Action/HelperBroker.php'
  6. /** Zend_Controller_Plugin_Broker */ 
  7. require_once 'Zend/Controller/Plugin/Broker.php'
  8. class Zend_Controller_Front 
  9.   protected $_baseUrl = null; 
  10.   protected $_controllerDir = null; 
  11.   protected $_dispatcher = null; 
  12.   protected static $_instance = null; 
  13.   protected $_invokeParams = array(); 
  14.   protected $_moduleControllerDirectoryName = 'controllers'
  15.   protected $_plugins = null; 
  16.   protected $_request = null; 
  17.   protected $_response = null; 
  18.   protected $_returnResponse = false; 
  19.   protected $_router = null; 
  20.   protected $_throwExceptions = false; 
  21.   protected function __construct() 
  22.   { 
  23.     $this->_plugins = new Zend_Controller_Plugin_Broker(); 
  24.   } 
  25.   private function __clone() 
  26.   { 
  27.   } 
  28.   public static function getInstance() 
  29.   { 
  30.     if (null === self::$_instance) { 
  31.       self::$_instance = new self(); 
  32.     } 
  33.     return self::$_instance
  34.   } 
  35.   public function resetInstance() 
  36.   { 
  37.     $reflection = new ReflectionObject($this); 
  38.     foreach ($reflection->getProperties() as $property) { 
  39.       $name = $property->getName(); 
  40.       switch ($name) { 
  41.         case '_instance'
  42.           break
  43.         case '_controllerDir'
  44.         case '_invokeParams'
  45.           $this->{$name} = array(); 
  46.           break
  47.         case '_plugins'
  48.           $this->{$name} = new Zend_Controller_Plugin_Broker(); 
  49.           break
  50.         case '_throwExceptions'
  51.         case '_returnResponse'
  52.           $this->{$name} = false; 
  53.           break
  54.         case '_moduleControllerDirectoryName'
  55.           $this->{$name} = 'controllers'
  56.           break
  57.         default
  58.           $this->{$name} = null; 
  59.           break
  60.       } 
  61.     } 
  62.     Zend_Controller_Action_HelperBroker::resetHelpers(); 
  63.   } 
  64.   public static function run($controllerDirectory
  65.   { 
  66.     self::getInstance() 
  67.       ->setControllerDirectory($controllerDirectory
  68.       ->dispatch(); 
  69.   } 
  70.   public function addControllerDirectory($directory$module = null) 
  71.   { 
  72.     $this->getDispatcher()->addControllerDirectory($directory$module); 
  73.     return $this
  74.   } 
  75.   public function setControllerDirectory($directory$module = null) 
  76.   { 
  77.     $this->getDispatcher()->setControllerDirectory($directory$module); 
  78.     return $this
  79.   } 
  80.   public function getControllerDirectory($name = null) 
  81.   { 
  82.     return $this->getDispatcher()->getControllerDirectory($name); 
  83.   } 
  84.   public function removeControllerDirectory($module
  85.   { 
  86.     return $this->getDispatcher()->removeControllerDirectory($module); 
  87.   } 
  88.   public function addModuleDirectory($path
  89.   { 
  90.     try{ 
  91.       $dir = new DirectoryIterator($path); 
  92.     } catch(Exception $e) { 
  93.       require_once 'Zend/Controller/Exception.php'
  94.       throw new Zend_Controller_Exception("Directory $path not readable", 0, $e); 
  95.     } 
  96.     foreach ($dir as $file) { 
  97.       if ($file->isDot() || !$file->isDir()) { 
  98.         continue
  99.       } 
  100.       $module  = $file->getFilename(); 
  101.       // Don't use SCCS directories as modules 
  102.       if (preg_match('/^[^a-z]/i'$module) || ('CVS' == $module)) { 
  103.         continue
  104.       } 
  105.       $moduleDir = $file->getPathname() . DIRECTORY_SEPARATOR . $this->getModuleControllerDirectoryName(); 
  106.       $this->addControllerDirectory($moduleDir$module); 
  107.     } 
  108.     return $this
  109.   } 
  110.   public function getModuleDirectory($module = null) 
  111.   { 
  112.     if (null === $module) { 
  113.       $request = $this->getRequest(); 
  114.       if (null !== $request) { 
  115.         $module = $this->getRequest()->getModuleName(); 
  116.       } 
  117.       if (emptyempty($module)) { 
  118.         $module = $this->getDispatcher()->getDefaultModule(); 
  119.       } 
  120.     } 
  121.     $controllerDir = $this->getControllerDirectory($module); 
  122.     if ((null === $controllerDir) || !is_string($controllerDir)) { 
  123.       return null; 
  124.     } 
  125.     return dirname($controllerDir); 
  126.   } 
  127.   public function setModuleControllerDirectoryName($name = 'controllers'
  128.   { 
  129.     $this->_moduleControllerDirectoryName = (string) $name
  130.     return $this
  131.   } 
  132.   public function getModuleControllerDirectoryName() 
  133.   { 
  134.     return $this->_moduleControllerDirectoryName; 
  135.   } 
  136.   public function setDefaultControllerName($controller
  137.   { 
  138.     $dispatcher = $this->getDispatcher(); 
  139.     $dispatcher->setDefaultControllerName($controller); 
  140.     return $this
  141.   } 
  142.   public function getDefaultControllerName() 
  143.   { 
  144.     return $this->getDispatcher()->getDefaultControllerName(); 
  145.   } 
  146.   public function setDefaultAction($action
  147.   { 
  148.     $dispatcher = $this->getDispatcher(); 
  149.     $dispatcher->setDefaultAction($action); 
  150.     return $this
  151.   } 
  152.   public function getDefaultAction() 
  153.   { 
  154.     return $this->getDispatcher()->getDefaultAction(); 
  155.   } 
  156.   public function setDefaultModule($module
  157.   { 
  158.     $dispatcher = $this->getDispatcher(); 
  159.     $dispatcher->setDefaultModule($module); 
  160.     return $this
  161.   } 
  162.   public function getDefaultModule() 
  163.   { 
  164.     return $this->getDispatcher()->getDefaultModule(); 
  165.   } 
  166.   public function setRequest($request
  167.   { 
  168.     ........................... 
  169.     return $this
  170.   } 
  171.   public function getRequest() 
  172.   { 
  173.     return $this->_request; 
  174.   } 
  175.   public function setRouter($router
  176.   { 
  177.     .................... 
  178.     return $this
  179.   } 
  180.   public function getRouter() 
  181.   { 
  182.     .................. 
  183.     return $this->_router; 
  184.   } 
  185.   public function setBaseUrl($base = null) 
  186.   { 
  187.     .............. 
  188.     return $this
  189.   } 
  190.   public function getBaseUrl() 
  191.   { 
  192.     return $this->_baseUrl; 
  193.   } 
  194.   /** 
  195.    * Set the dispatcher object. The dispatcher is responsible for 
  196.    * taking a Zend_Controller_Dispatcher_Token object, instantiating the controller, and 
  197.    * call the action method of the controller. 
  198.    * 
  199.    * @param Zend_Controller_Dispatcher_Interface $dispatcher 
  200.    * @return Zend_Controller_Front 
  201.    */ 
  202.   public function setDispatcher(Zend_Controller_Dispatcher_Interface $dispatcher
  203.   { 
  204.     $this->_dispatcher = $dispatcher
  205.     return $this
  206.   } 
  207.   /** 
  208.    * Return the dispatcher object. 
  209.    * 
  210.    * @return Zend_Controller_Dispatcher_Interface 
  211.    */ 
  212.   public function getDispatcher() 
  213.   { 
  214.     /** 
  215.      * Instantiate the default dispatcher if one was not set. 
  216.      */ 
  217.     if (!$this->_dispatcher instanceof Zend_Controller_Dispatcher_Interface) { 
  218.       require_once 'Zend/Controller/Dispatcher/Standard.php'
  219.       $this->_dispatcher = new Zend_Controller_Dispatcher_Standard(); 
  220.     } 
  221.     return $this->_dispatcher; 
  222.   } 
  223.   public function setResponse($response
  224.   {.................. 
  225.     return $this
  226.   } 
  227.   public function getResponse() 
  228.   { 
  229.     return $this->_response; 
  230.   } 
  231.   public function setParam($name$value
  232.   { 
  233.     $name = (string) $name
  234.     $this->_invokeParams[$name] = $value
  235.     return $this
  236.   } 
  237.   public function setParams(array $params
  238.   { 
  239.     $this->_invokeParams = array_merge($this->_invokeParams, $params); 
  240.     return $this
  241.   } 
  242.   public function getParam($name
  243.   { 
  244.     if(isset($this->_invokeParams[$name])) { 
  245.       return $this->_invokeParams[$name]; 
  246.     } 
  247.     return null; 
  248.   } 
  249.   public function getParams() 
  250.   { 
  251.     return $this->_invokeParams; 
  252.   } 
  253.   public function clearParams($name = null) 
  254.   { 
  255.     if (null === $name) { 
  256.       $this->_invokeParams = array(); 
  257.     } elseif (is_string($name) && isset($this->_invokeParams[$name])) { 
  258.       unset($this->_invokeParams[$name]); 
  259.     } elseif (is_array($name)) { 
  260.       foreach ($name as $key) { 
  261.         if (is_string($key) && isset($this->_invokeParams[$key])) { 
  262.           unset($this->_invokeParams[$key]); 
  263.         } 
  264.       } 
  265.     } 
  266.     return $this
  267.   } 
  268.   public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin$stackIndex = null) 
  269.   { 
  270.     $this->_plugins->registerPlugin($plugin$stackIndex); 
  271.     return $this
  272.   } 
  273.   public function unregisterPlugin($plugin
  274.   { 
  275.     $this->_plugins->unregisterPlugin($plugin); 
  276.     return $this
  277.   } 
  278.   public function hasPlugin($class
  279.   { 
  280.     return $this->_plugins->hasPlugin($class); 
  281.   } 
  282.   public function getPlugin($class
  283.   { 
  284.     return $this->_plugins->getPlugin($class); 
  285.   } 
  286.   public function getPlugins() 
  287.   { 
  288.     return $this->_plugins->getPlugins(); 
  289.   } 
  290.   public function throwExceptions($flag = null) 
  291.   { 
  292.     ..................... 
  293.     return $this->_throwExceptions; 
  294.   } 
  295.   public function returnResponse($flag = null) 
  296.   { 
  297.     ................ 
  298.     return $this->_returnResponse; 
  299.   } 
  300.   /** 
  301.    * Dispatch an HTTP request to a controller/action. 
  302.    * 
  303.    * @param Zend_Controller_Request_Abstract|null $request 
  304.    * @param Zend_Controller_Response_Abstract|null $response 
  305.    * @return void|Zend_Controller_Response_Abstract Returns response object if returnResponse() is true 
  306.    */ 
  307.   public function dispatch(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null) 
  308.   { 
  309.     if (!$this->getParam('noErrorHandler') && !$this->_plugins->hasPlugin('Zend_Controller_Plugin_ErrorHandler')) { 
  310.       // Register with stack index of 100 
  311.       require_once 'Zend/Controller/Plugin/ErrorHandler.php'
  312.       $this->_plugins->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(), 100); 
  313.     } 
  314.     if (!$this->getParam('noViewRenderer') && !Zend_Controller_Action_HelperBroker::hasHelper('viewRenderer')) { 
  315.       require_once 'Zend/Controller/Action/Helper/ViewRenderer.php'
  316.       Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-80, new Zend_Controller_Action_Helper_ViewRenderer()); 
  317.     } 
  318.     /** 
  319.      * Instantiate default request object (HTTP version) if none provided 
  320.      */ 
  321.     if (null !== $request) { 
  322.       $this->setRequest($request); 
  323.     } elseif ((null === $request) && (null === ($request = $this->getRequest()))) { 
  324.       require_once 'Zend/Controller/Request/Http.php'
  325.       $request = new Zend_Controller_Request_Http(); 
  326.       $this->setRequest($request); 
  327.     } 
  328.     /** 
  329.      * Set base URL of request object, if available 
  330.      */ 
  331.     if (is_callable(array($this->_request, 'setBaseUrl'))) { 
  332.       if (null !== $this->_baseUrl) { 
  333.         $this->_request->setBaseUrl($this->_baseUrl); 
  334.       } 
  335.     } 
  336.     /** 
  337.      * Instantiate default response object (HTTP version) if none provided 
  338.      */ 
  339.     if (null !== $response) { 
  340.       $this->setResponse($response); 
  341.     } elseif ((null === $this->_response) && (null === ($this->_response = $this->getResponse()))) { 
  342.       require_once 'Zend/Controller/Response/Http.php'
  343.       $response = new Zend_Controller_Response_Http(); 
  344.       $this->setResponse($response); 
  345.     } 
  346.     /** 
  347.      * Register request and response objects with plugin broker 
  348.      */ 
  349.     $this->_plugins 
  350.        ->setRequest($this->_request) 
  351.        ->setResponse($this->_response); 
  352.     /** 
  353.      * Initialize router 
  354.      */ 
  355.     $router = $this->getRouter(); 
  356.     $router->setParams($this->getParams()); 
  357.     /** 
  358.      * Initialize dispatcher 
  359.      */ 
  360.     $dispatcher = $this->getDispatcher(); 
  361.     $dispatcher->setParams($this->getParams()) 
  362.           ->setResponse($this->_response); 
  363.     // Begin dispatch 
  364.     try { 
  365.       /** 
  366.        * Route request to controller/action, if a router is provided 
  367.        */ 
  368.       /** 
  369.       * Notify plugins of router startup 
  370.       */ 
  371.       $this->_plugins->routeStartup($this->_request); 
  372.       try { 
  373.         $router->route($this->_request); 
  374.       } catch (Exception $e) { 
  375.         if ($this->throwExceptions()) { 
  376.           throw $e
  377.         } 
  378.         $this->_response->setException($e); 
  379.       } 
  380.       /** 
  381.       * Notify plugins of router completion 
  382.       */ 
  383.       $this->_plugins->routeShutdown($this->_request); 
  384.       /** 
  385.        * Notify plugins of dispatch loop startup 
  386.        */ 
  387.       $this->_plugins->dispatchLoopStartup($this->_request); 
  388.       /** 
  389.        * Attempt to dispatch the controller/action. If the $this->_request 
  390.        * indicates that it needs to be dispatched, move to the next 
  391.        * action in the request. 
  392.        */ 
  393.       do { 
  394.         $this->_request->setDispatched(true); 
  395.         /** 
  396.          * Notify plugins of dispatch startup 
  397.          */ 
  398.         $this->_plugins->preDispatch($this->_request); 
  399.         /** 
  400.          * Skip requested action if preDispatch() has reset it 
  401.          */ 
  402.         if (!$this->_request->isDispatched()) { 
  403.           continue
  404.         } 
  405.         /** 
  406.          * Dispatch request 
  407.          */ 
  408.         try { 
  409.           $dispatcher->dispatch($this->_request, $this->_response); 
  410.         } catch (Exception $e) { 
  411.           if ($this->throwExceptions()) { 
  412.             throw $e
  413.           } 
  414.           $this->_response->setException($e); 
  415.         } 
  416.         /** 
  417.          * Notify plugins of dispatch completion 
  418.          */ 
  419.         $this->_plugins->postDispatch($this->_request); 
  420.       } while (!$this->_request->isDispatched()); 
  421.     } catch (Exception $e) { 
  422.       if ($this->throwExceptions()) { 
  423.         throw $e
  424.       } 
  425.       $this->_response->setException($e); 
  426.     } 
  427.     /** 
  428.      * Notify plugins of dispatch loop completion 
  429.      */ 
  430.     try { 
  431.       $this->_plugins->dispatchLoopShutdown(); 
  432.     } catch (Exception $e) { 
  433.       if ($this->throwExceptions()) { 
  434.         throw $e
  435.       } 
  436.       $this->_response->setException($e); 
  437.     } 
  438.     if ($this->returnResponse()) { 
  439.       return $this->_response; 
  440.     } 
  441.     $this->_response->sendResponse(); 
  442.   } 

以上对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类,基于标准分发器来修改功能。

需要子类化分发器的可能原因包括:期望在动作控制器中使用不同的类和方法命名模式,或者期望使用不同的分发方式,比如分发到控制器目录下的动作文件,而不是控制器类的动作方法。

Tags: Framework Zend_Controller_Dispatcher

分享到: