当前位置: 移动技术网 > IT编程>开发语言>PHP > Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解

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

2017年12月12日  | 移动技术网IT编程  | 我要评论

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

分发器的具体实现

zend framework的分发器zend_controller_dispatcher设计主要有,如下类和接口组成:

├── dispatcher
│   ├── abstract.php
│   ├── exception.php
│   ├── interface.php
│   └── standard.php

zend_controller_dispatcher_interface

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

interface zend_controller_dispatcher_interface
{
  public function formatcontrollername($unformatted);
  public function formatmodulename($unformatted);
  public function formatactionname($unformatted);
  public function isdispatchable(zend_controller_request_abstract $request);
  public function setparam($name, $value);
  public function setparams(array $params);
  public function getparam($name);
  public function getparams();
  public function clearparams($name = null);
  public function setresponse(zend_controller_response_abstract $response = null);
  public function getresponse();
  public function addcontrollerdirectory($path, $args = null);
  public function setcontrollerdirectory($path);
  public function getcontrollerdirectory();
  public function dispatch(zend_controller_request_abstract $request, zend_controller_response_abstract $response);
  public function isvalidmodule($module);
  public function getdefaultmodule();
  public function getdefaultcontrollername();
  public function getdefaultaction();
}

zend_controller_dispatcher_abstract

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

<?php
/** zend_controller_dispatcher_interface */
require_once 'zend/controller/dispatcher/interface.php';
abstract class zend_controller_dispatcher_abstract implements zend_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('-', '.');
  public function __construct(array $params = array())
  {
    $this->setparams($params);
  }
  public function formatcontrollername($unformatted)
  {
    return ucfirst($this->_formatname($unformatted)) . 'controller';
  }
  public function formatactionname($unformatted)
  {
    $formatted = $this->_formatname($unformatted, true);
    return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1) . 'action';
  }
  public function _verifydelimiter($spec)
  {
    if (is_string($spec)) {
      return (array) $spec;
    } elseif (is_array($spec)) {
      $allstrings = true;
      foreach ($spec as $delim) {
        if (!is_string($delim)) {
          $allstrings = false;
          break;
        }
      }
      if (!$allstrings) {
        require_once 'zend/controller/dispatcher/exception.php';
        throw new zend_controller_dispatcher_exception('word delimiter array must contain only strings');
      }
      return $spec;
    }
    require_once 'zend/controller/dispatcher/exception.php';
    throw new zend_controller_dispatcher_exception('invalid word delimiter');
  }
  public function getworddelimiter()
  {
    return $this->_worddelimiter;
  }
  public function setworddelimiter($spec)
  {
    $spec = $this->_verifydelimiter($spec);
    $this->_worddelimiter = $spec;
    return $this;
  }
  public function getpathdelimiter()
  {
    return $this->_pathdelimiter;
  }
  public function setpathdelimiter($spec)
  {
    if (!is_string($spec)) {
      require_once 'zend/controller/dispatcher/exception.php';
      throw new zend_controller_dispatcher_exception('invalid path delimiter');
    }
    $this->_pathdelimiter = $spec;
    return $this;
  }
  protected function _formatname($unformatted, $isaction = false)
  {
    // preserve directories
    if (!$isaction) {
      $segments = explode($this->getpathdelimiter(), $unformatted);
    } else {
      $segments = (array) $unformatted;
    }
    foreach ($segments as $key => $segment) {
      $segment    = str_replace($this->getworddelimiter(), ' ', strtolower($segment));
      $segment    = preg_replace('/[^a-z0-9 ]/', '', $segment);
      $segments[$key] = str_replace(' ', '', ucwords($segment));
    }
    return implode('_', $segments);
  }
  public function getfrontcontroller()
  {
    if (null === $this->_frontcontroller) {
      require_once 'zend/controller/front.php';
      $this->_frontcontroller = zend_controller_front::getinstance();
    }
    return $this->_frontcontroller;
  }
  public function setfrontcontroller(zend_controller_front $controller)
  {
    $this->_frontcontroller = $controller;
    return $this;
  }
  public function setparam($name, $value)
  {
    $name = (string) $name;
    $this->_invokeparams[$name] = $value;
    return $this;
  }
  public function setparams(array $params)
  {
    $this->_invokeparams = array_merge($this->_invokeparams, $params);
    return $this;
  }
  public function getparam($name)
  {
    if(isset($this->_invokeparams[$name])) {
      return $this->_invokeparams[$name];
    }
    return null;
  }
  public function getparams()
  {
    return $this->_invokeparams;
  }
  public function clearparams($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 ($name as $key) {
        if (is_string($key) && isset($this->_invokeparams[$key])) {
          unset($this->_invokeparams[$key]);
        }
      }
    }
    return $this;
  }
  public function setresponse(zend_controller_response_abstract $response = null)
  {
    $this->_response = $response;
    return $this;
  }
  public function getresponse()
  {
    return $this->_response;
  }
  public function setdefaultcontrollername($controller)
  {
    $this->_defaultcontroller = (string) $controller;
    return $this;
  }
  public function getdefaultcontrollername()
  {
    return $this->_defaultcontroller;
  }
  public function setdefaultaction($action)
  {
    $this->_defaultaction = (string) $action;
    return $this;
  }
  public function getdefaultaction()
  {
    return $this->_defaultaction;
  }
  public function setdefaultmodule($module)
  {
    $this->_defaultmodule = (string) $module;
    return $this;
  }
  public function getdefaultmodule()
  {
    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';
class zend_controller_dispatcher_standard extends zend_controller_dispatcher_abstract
{
  protected $_curdirectory;
  protected $_curmodule;
  protected $_controllerdirectory = array();
  public function __construct(array $params = array())
  {
    parent::__construct($params);
    $this->_curmodule = $this->getdefaultmodule();
  }
  public function addcontrollerdirectory($path, $module = null)
  {
    if (null === $module) {
      $module = $this->_defaultmodule;
    }
    $module = (string) $module;
    $path  = rtrim((string) $path, '/\\');
    $this->_controllerdirectory[$module] = $path;
    return $this;
  }
  public function setcontrollerdirectory($directory, $module = null)
  {
    $this->_controllerdirectory = array();
    if (is_string($directory)) {
      $this->addcontrollerdirectory($directory, $module);
    } elseif (is_array($directory)) {
      foreach ((array) $directory as $module => $path) {
        $this->addcontrollerdirectory($path, $module);
      }
    } else {
      require_once 'zend/controller/exception.php';
      throw new zend_controller_exception('controller directory spec must be either a string or an array');
    }
    return $this;
  }
  public function getcontrollerdirectory($module = null)
  {
    if (null === $module) {
      return $this->_controllerdirectory;
    }
    $module = (string) $module;
    if (array_key_exists($module, $this->_controllerdirectory)) {
      return $this->_controllerdirectory[$module];
    }
    return null;
  }
  public function removecontrollerdirectory($module)
  {
    $module = (string) $module;
    if (array_key_exists($module, $this->_controllerdirectory)) {
      unset($this->_controllerdirectory[$module]);
      return true;
    }
    return false;
  }
  public function formatmodulename($unformatted)
  {
    if (($this->_defaultmodule == $unformatted) && !$this->getparam('prefixdefaultmodule')) {
      return $unformatted;
    }
    return ucfirst($this->_formatname($unformatted));
  }
  public function formatclassname($modulename, $classname)
  {
    return $this->formatmodulename($modulename) . '_' . $classname;
  }
  public function classtofilename($class)
  {
    return str_replace('_', directory_separator, $class) . '.php';
  }
  public function isdispatchable(zend_controller_request_abstract $request)
  {
    $classname = $this->getcontrollerclass($request);
    if (!$classname) {
      return false;
    }
    $finalclass = $classname;
    if (($this->_defaultmodule != $this->_curmodule)
      || $this->getparam('prefixdefaultmodule'))
    {
      $finalclass = $this->formatclassname($this->_curmodule, $classname);
    }
    if (class_exists($finalclass, false)) {
      return true;
    }
    $filespec  = $this->classtofilename($classname);
    $dispatchdir = $this->getdispatchdirectory();
    $test    = $dispatchdir . directory_separator . $filespec;
    return zend_loader::isreadable($test);
  }
  public function dispatch(zend_controller_request_abstract $request, zend_controller_response_abstract $response)
  {
    $this->setresponse($response);
    /**
     * get controller class
     */
    if (!$this->isdispatchable($request)) {
      $controller = $request->getcontrollername();
      if (!$this->getparam('usedefaultcontrolleralways') && !empty($controller)) {
        require_once 'zend/controller/dispatcher/exception.php';
        throw new zend_controller_dispatcher_exception('invalid controller specified (' . $request->getcontrollername() . ')');
      }
      $classname = $this->getdefaultcontrollerclass($request);
    } else {
      $classname = $this->getcontrollerclass($request);
      if (!$classname) {
        $classname = $this->getdefaultcontrollerclass($request);
      }
    }
    /**
     * load the controller class file
     */
    $classname = $this->loadclass($classname);
    /**
     * instantiate controller with request, response, and invocation
     * arguments; throw exception if it's not an action controller
     */
    $controller = new $classname($request, $this->getresponse(), $this->getparams());
    if (!($controller instanceof zend_controller_action_interface) &&
      !($controller instanceof zend_controller_action)) {
      require_once 'zend/controller/dispatcher/exception.php';
      throw new zend_controller_dispatcher_exception(
        'controller "' . $classname . '" is not an instance of zend_controller_action_interface'
      );
    }
    /**
     * retrieve the action name
     */
    $action = $this->getactionmethod($request);
    /**
     * dispatch the method call
     */
    $request->setdispatched(true);
    // by default, buffer output
    $disableob = $this->getparam('disableoutputbuffering');
    $oblevel  = ob_get_level();
    if (empty($disableob)) {
      ob_start();
    }
    try {
      $controller->dispatch($action);
    } catch (exception $e) {
      // clean output buffer on error
      $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);
    }
    // destroy the page controller instance and reflection objects
    $controller = null;
  }
  public function loadclass($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';
      throw new zend_controller_dispatcher_exception('cannot load controller class "' . $classname . '" from file "' . $loadfile . "'");
    }
    if (!class_exists($finalclass, false)) {
      require_once 'zend/controller/dispatcher/exception.php';
      throw new zend_controller_dispatcher_exception('invalid controller class ("' . $finalclass . '")');
    }
    return $finalclass;
  }
  public function getcontrollerclass(zend_controller_request_abstract $request)
  {
    $controllername = $request->getcontrollername();
    if (empty($controllername)) {
      if (!$this->getparam('usedefaultcontrolleralways')) {
        return false;
      }
      $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';
      throw new zend_controller_exception('no default module defined for this application');
    }
    return $classname;
  }
  public function isvalidmodule($module)
  {
    if (!is_string($module)) {
      return false;
    }
    $module    = strtolower($module);
    $controllerdir = $this->getcontrollerdirectory();
    foreach (array_keys($controllerdir) as $modulename) {
      if ($module == strtolower($modulename)) {
        return true;
      }
    }
    return false;
  }
  public function getdefaultcontrollerclass(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;
  }
  public function getdispatchdirectory()
  {
    return $this->_curdirectory;
  }
  public function getactionmethod(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';
class zend_controller_front
{
  protected $_baseurl = null;
  protected $_controllerdir = null;
  protected $_dispatcher = null;
  protected static $_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;
  protected function __construct()
  {
    $this->_plugins = new zend_controller_plugin_broker();
  }
  private function __clone()
  {
  }
  public static function getinstance()
  {
    if (null === self::$_instance) {
      self::$_instance = new self();
    }
    return self::$_instance;
  }
  public function resetinstance()
  {
    $reflection = new reflectionobject($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} = new zend_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();
  }
  public static function run($controllerdirectory)
  {
    self::getinstance()
      ->setcontrollerdirectory($controllerdirectory)
      ->dispatch();
  }
  public function addcontrollerdirectory($directory, $module = null)
  {
    $this->getdispatcher()->addcontrollerdirectory($directory, $module);
    return $this;
  }
  public function setcontrollerdirectory($directory, $module = null)
  {
    $this->getdispatcher()->setcontrollerdirectory($directory, $module);
    return $this;
  }
  public function getcontrollerdirectory($name = null)
  {
    return $this->getdispatcher()->getcontrollerdirectory($name);
  }
  public function removecontrollerdirectory($module)
  {
    return $this->getdispatcher()->removecontrollerdirectory($module);
  }
  public function addmoduledirectory($path)
  {
    try{
      $dir = new directoryiterator($path);
    } catch(exception $e) {
      require_once 'zend/controller/exception.php';
      throw new zend_controller_exception("directory $path not readable", 0, $e);
    }
    foreach ($dir as $file) {
      if ($file->isdot() || !$file->isdir()) {
        continue;
      }
      $module  = $file->getfilename();
      // don't use sccs directories as modules
      if (preg_match('/^[^a-z]/i', $module) || ('cvs' == $module)) {
        continue;
      }
      $moduledir = $file->getpathname() . directory_separator . $this->getmodulecontrollerdirectoryname();
      $this->addcontrollerdirectory($moduledir, $module);
    }
    return $this;
  }
  public function getmoduledirectory($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)) {
      return null;
    }
    return dirname($controllerdir);
  }
  public function setmodulecontrollerdirectoryname($name = 'controllers')
  {
    $this->_modulecontrollerdirectoryname = (string) $name;
    return $this;
  }
  public function getmodulecontrollerdirectoryname()
  {
    return $this->_modulecontrollerdirectoryname;
  }
  public function setdefaultcontrollername($controller)
  {
    $dispatcher = $this->getdispatcher();
    $dispatcher->setdefaultcontrollername($controller);
    return $this;
  }
  public function getdefaultcontrollername()
  {
    return $this->getdispatcher()->getdefaultcontrollername();
  }
  public function setdefaultaction($action)
  {
    $dispatcher = $this->getdispatcher();
    $dispatcher->setdefaultaction($action);
    return $this;
  }
  public function getdefaultaction()
  {
    return $this->getdispatcher()->getdefaultaction();
  }
  public function setdefaultmodule($module)
  {
    $dispatcher = $this->getdispatcher();
    $dispatcher->setdefaultmodule($module);
    return $this;
  }
  public function getdefaultmodule()
  {
    return $this->getdispatcher()->getdefaultmodule();
  }
  public function setrequest($request)
  {
    ...........................
    return $this;
  }
  public function getrequest()
  {
    return $this->_request;
  }
  public function setrouter($router)
  {
    ....................
    return $this;
  }
  public function getrouter()
  {
    ..................
    return $this->_router;
  }
  public function setbaseurl($base = null)
  {
    ..............
    return $this;
  }
  public function getbaseurl()
  {
    return $this->_baseurl;
  }
  /**
   * set the dispatcher object. the dispatcher is responsible for
   * taking a zend_controller_dispatcher_token object, instantiating the controller, and
   * call the action method of the controller.
   *
   * @param zend_controller_dispatcher_interface $dispatcher
   * @return zend_controller_front
   */
  public function setdispatcher(zend_controller_dispatcher_interface $dispatcher)
  {
    $this->_dispatcher = $dispatcher;
    return $this;
  }
  /**
   * return the dispatcher object.
   *
   * @return zend_controller_dispatcher_interface
   */
  public function getdispatcher()
  {
    /**
     * instantiate the default dispatcher if one was not set.
     */
    if (!$this->_dispatcher instanceof zend_controller_dispatcher_interface) {
      require_once 'zend/controller/dispatcher/standard.php';
      $this->_dispatcher = new zend_controller_dispatcher_standard();
    }
    return $this->_dispatcher;
  }
  public function setresponse($response)
  {..................
    return $this;
  }
  public function getresponse()
  {
    return $this->_response;
  }
  public function setparam($name, $value)
  {
    $name = (string) $name;
    $this->_invokeparams[$name] = $value;
    return $this;
  }
  public function setparams(array $params)
  {
    $this->_invokeparams = array_merge($this->_invokeparams, $params);
    return $this;
  }
  public function getparam($name)
  {
    if(isset($this->_invokeparams[$name])) {
      return $this->_invokeparams[$name];
    }
    return null;
  }
  public function getparams()
  {
    return $this->_invokeparams;
  }
  public function clearparams($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 ($name as $key) {
        if (is_string($key) && isset($this->_invokeparams[$key])) {
          unset($this->_invokeparams[$key]);
        }
      }
    }
    return $this;
  }
  public function registerplugin(zend_controller_plugin_abstract $plugin, $stackindex = null)
  {
    $this->_plugins->registerplugin($plugin, $stackindex);
    return $this;
  }
  public function unregisterplugin($plugin)
  {
    $this->_plugins->unregisterplugin($plugin);
    return $this;
  }
  public function hasplugin($class)
  {
    return $this->_plugins->hasplugin($class);
  }
  public function getplugin($class)
  {
    return $this->_plugins->getplugin($class);
  }
  public function getplugins()
  {
    return $this->_plugins->getplugins();
  }
  public function throwexceptions($flag = null)
  {
    .....................
    return $this->_throwexceptions;
  }
  public function returnresponse($flag = null)
  {
    ................
    return $this->_returnresponse;
  }
  /**
   * dispatch an http request to a controller/action.
   *
   * @param zend_controller_request_abstract|null $request
   * @param zend_controller_response_abstract|null $response
   * @return void|zend_controller_response_abstract returns response object if returnresponse() is true
   */
  public function dispatch(zend_controller_request_abstract $request = null, zend_controller_response_abstract $response = null)
  {
    if (!$this->getparam('noerrorhandler') && !$this->_plugins->hasplugin('zend_controller_plugin_errorhandler')) {
      // register with stack index of 100
      require_once 'zend/controller/plugin/errorhandler.php';
      $this->_plugins->registerplugin(new zend_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, new zend_controller_action_helper_viewrenderer());
    }
    /**
     * instantiate default request object (http version) if none provided
     */
    if (null !== $request) {
      $this->setrequest($request);
    } elseif ((null === $request) && (null === ($request = $this->getrequest()))) {
      require_once 'zend/controller/request/http.php';
      $request = new zend_controller_request_http();
      $this->setrequest($request);
    }
    /**
     * set base url of request object, if available
     */
    if (is_callable(array($this->_request, 'setbaseurl'))) {
      if (null !== $this->_baseurl) {
        $this->_request->setbaseurl($this->_baseurl);
      }
    }
    /**
     * instantiate default response object (http version) if none provided
     */
    if (null !== $response) {
      $this->setresponse($response);
    } elseif ((null === $this->_response) && (null === ($this->_response = $this->getresponse()))) {
      require_once 'zend/controller/response/http.php';
      $response = new zend_controller_response_http();
      $this->setresponse($response);
    }
    /**
     * register request and response objects with plugin broker
     */
    $this->_plugins
       ->setrequest($this->_request)
       ->setresponse($this->_response);
    /**
     * initialize router
     */
    $router = $this->getrouter();
    $router->setparams($this->getparams());
    /**
     * initialize dispatcher
     */
    $dispatcher = $this->getdispatcher();
    $dispatcher->setparams($this->getparams())
          ->setresponse($this->_response);
    // begin dispatch
    try {
      /**
       * route request to controller/action, if a router is provided
       */
      /**
      * notify plugins of router startup
      */
      $this->_plugins->routestartup($this->_request);
      try {
        $router->route($this->_request);
      } catch (exception $e) {
        if ($this->throwexceptions()) {
          throw $e;
        }
        $this->_response->setexception($e);
      }
      /**
      * notify plugins of router completion
      */
      $this->_plugins->routeshutdown($this->_request);
      /**
       * notify plugins of dispatch loop startup
       */
      $this->_plugins->dispatchloopstartup($this->_request);
      /**
       * attempt to dispatch the controller/action. if the $this->_request
       * indicates that it needs to be dispatched, move to the next
       * action in the request.
       */
      do {
        $this->_request->setdispatched(true);
        /**
         * notify plugins of dispatch startup
         */
        $this->_plugins->predispatch($this->_request);
        /**
         * skip requested action if predispatch() has reset it
         */
        if (!$this->_request->isdispatched()) {
          continue;
        }
        /**
         * dispatch request
         */
        try {
          $dispatcher->dispatch($this->_request, $this->_response);
        } catch (exception $e) {
          if ($this->throwexceptions()) {
            throw $e;
          }
          $this->_response->setexception($e);
        }
        /**
         * notify plugins of dispatch completion
         */
        $this->_plugins->postdispatch($this->_request);
      } while (!$this->_request->isdispatched());
    } catch (exception $e) {
      if ($this->throwexceptions()) {
        throw $e;
      }
      $this->_response->setexception($e);
    }
    /**
     * notify plugins of dispatch loop completion
     */
    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相关内容感兴趣的读者可查看本站专题:《zend framework框架入门教程》、《php优秀开发框架总结》、《yii框架入门及常用技巧总结》、《thinkphp入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

希望本文所述对大家php程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网