本文实例讲述了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程序设计有所帮助。
【说明】:
本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:)!