Zend Framework教程之分發(fā)器Zend_Controller_Dispatcher用法詳解
本文實(shí)例講述了Zend Framework教程之分發(fā)器Zend_Controller_Dispatcher用法。分享給大家供大家參考,具體如下:
分發(fā)器的具體實(shí)現(xiàn)
Zend Framework的分發(fā)器Zend_Controller_Dispatcher設(shè)計(jì)主要有,如下類(lèi)和接口組成:
├── Dispatcher
│ ├── Abstract.php
│ ├── Exception.php
│ ├── Interface.php
│ └── Standard.php
Zend_Controller_Dispatcher_Interface
定義了分發(fā)器提供的基本和標(biāo)準(zhǔn)功能。
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
實(shí)現(xiàn)了Zend_Controller_Dispatcher_Interface接口,提供了分發(fā)器提供的基本和標(biāo)準(zhǔn)功能的抽象父類(lèi)。
<?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繼承抽象類(lèi)Zend_Controller_Dispatcher_Abstract,定義了Zend_Controller_Dispatcher_Standard。Zend_Controller_Dispatcher_Standard是ZendFramework提供的基本的分發(fā)器,完成了分發(fā)功能。
<?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);
}
}
前端控制器和分發(fā)器
<?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();
}
}
以上對(duì)Zend_Controller_Front和Zend_Controller_Dispatcher做了簡(jiǎn)單的標(biāo)記,通過(guò)分析代碼不難看出,基本的運(yùn)行機(jī)制。
分發(fā)發(fā)生在前端控制器中的一個(gè)循環(huán)(loop)中。分發(fā)之前,前端控制器通過(guò)路由請(qǐng)求,找到用戶(hù)指定的模塊、控制器、動(dòng)作和可選參數(shù)。然后進(jìn)入分發(fā)循環(huán),分發(fā)請(qǐng)求。
分發(fā)器需要大量數(shù)據(jù)完成任務(wù)——它需要知道如何格式化控制器和動(dòng)作的名稱(chēng),到哪兒找到控制器類(lèi)文件,模塊名是否有效,以及基于其它可用信息判定請(qǐng)求是否能分發(fā)的API。
每次迭代(iteration)過(guò)程開(kāi)始時(shí),在請(qǐng)求對(duì)象中設(shè)置一個(gè)標(biāo)志指示該動(dòng)作已分發(fā)。如果在動(dòng)作或者前/后分發(fā)(pre/postDispatch)插件重置了該標(biāo)志,分發(fā)循環(huán)將繼續(xù)下去并試圖分發(fā)新的請(qǐng)求。通過(guò)改變請(qǐng)求中的控制器或者動(dòng)作并重置已分發(fā)標(biāo)志,開(kāi)發(fā)人員可以定制執(zhí)行一個(gè)請(qǐng)求鏈。
控制這種分發(fā)過(guò)程的動(dòng)作控制器方法是_forward();在任意的pre/postDispatch()或者動(dòng)作中調(diào)用該方法,并傳入動(dòng)作、控制器、模塊、以及可選的附加參數(shù),就可以進(jìn)入新的動(dòng)作。
自定義分發(fā)器
Zend_Controller_Dispatcher_Interface定義了下列所有分發(fā)器需要實(shí)現(xiàn)的方法。
不過(guò)大多數(shù)情況下,只需要簡(jiǎn)單地?cái)U(kuò)展抽象類(lèi)Zend_Controller_Dispatcher_Abstract,其中已經(jīng)定義好了上面的大部分方法?;蛘邤U(kuò)展Zend_Controller_Dispatcher_Standard類(lèi),基于標(biāo)準(zhǔn)分發(fā)器來(lái)修改功能。
需要子類(lèi)化分發(fā)器的可能原因包括:期望在動(dòng)作控制器中使用不同的類(lèi)和方法命名模式,或者期望使用不同的分發(fā)方式,比如分發(fā)到控制器目錄下的動(dòng)作文件,而不是控制器類(lèi)的動(dòng)作方法。
更多關(guān)于zend相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Zend FrameWork框架入門(mén)教程》、《php優(yōu)秀開(kāi)發(fā)框架總結(jié)》、《Yii框架入門(mén)及常用技巧總結(jié)》、《ThinkPHP入門(mén)教程》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
- Zend Framework教程之前端控制器Zend_Controller_Front用法詳解
- Zend Framework動(dòng)作控制器用法示例
- Zend Framework路由器用法實(shí)例詳解
- Zend Framework分發(fā)器用法示例
- Zend Framework過(guò)濾器Zend_Filter用法詳解
- Zend Framework實(shí)現(xiàn)自定義過(guò)濾器的方法
- Zend Framework校驗(yàn)器Zend_Validate用法詳解
- Zend Framework常用校驗(yàn)器詳解
- Zend Framework 2.0事件管理器(The EventManager)入門(mén)教程
- Zend Framework前端控制器用法示例
相關(guān)文章
在 Laravel 中動(dòng)態(tài)隱藏 API 字段的方法
這篇文章主要介紹了在 Laravel 中動(dòng)態(tài)隱藏 API 字段的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10
php數(shù)字運(yùn)算驗(yàn)證碼的實(shí)現(xiàn)代碼
這篇文章主要介紹了php實(shí)現(xiàn)數(shù)字運(yùn)算驗(yàn)證碼的方法,具有一定借鑒價(jià)值,需要的朋友可以參考下2015-07-07
php根據(jù)操作系統(tǒng)轉(zhuǎn)換文件名大小寫(xiě)的方法
這篇文章主要介紹了php根據(jù)操作系統(tǒng)轉(zhuǎn)換文件名大小寫(xiě)的方法,需要的朋友可以參考下2014-02-02
PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn)
本篇文章主要介紹了PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn),這個(gè)平時(shí)做的密碼驗(yàn)證有異曲同工之處,有需要的可以了解一下。2016-10-10
PHP創(chuàng)建PowerPoint2007文檔的方法
這篇文章主要介紹了PHP創(chuàng)建PowerPoint2007文檔的方法,通過(guò)PHP第三方插件PHPPowerPoint類(lèi)庫(kù)實(shí)現(xiàn)ppt文件的生成功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-12-12
ThinkPHP3.2框架自帶分頁(yè)功能實(shí)現(xiàn)方法示例
這篇文章主要介紹了ThinkPHP3.2框架自帶分頁(yè)功能實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了thinkPHP框架自帶分頁(yè)功能相關(guān)布局、樣式及后臺(tái)操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-05-05
用 Composer構(gòu)建自己的 PHP 框架之基礎(chǔ)準(zhǔn)備
這篇文章主要介紹了用 Composer構(gòu)建自己的 PHP 框架的基礎(chǔ)準(zhǔn)備工作,其實(shí)就是各種基礎(chǔ)知識(shí),想自己搭建php框架的童鞋可要看仔細(xì)了2014-10-10
php+mysql+ajax 局部刷新點(diǎn)贊/取消點(diǎn)贊功能(每個(gè)賬號(hào)只點(diǎn)贊一次)
這篇文章主要介紹了php+mysql+ajax 局部刷新點(diǎn)贊/取消點(diǎn)贊功能(每個(gè)賬號(hào)只點(diǎn)贊一次),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07

