Диспетчеризация — это процесс принятия объекта запроса
(Zend_Controller_Request_Abstract), извлечения
содержащихся в нем имени модуля, имени контроллера, имени действия и
необязательных параметров, затем инстанцирования контроллера и
вызова действия в нем. Если не найдены модуль, контроллер или
действие, то будут использоваться значения по умолчанию.
Zend_Controller_Dispatcher_Standard определяет
index как значение по умолчанию для контроллера и
действия, и default - для модуля, но позволяет
разработчику изменять эти значения, используя
setDefaultController(),
setDefaultAction() и setDefaultModule(),
соответственно.
![]() |
Модуль, используемый по умолчанию |
|---|---|
|
При создании приложения, состоящего из модулей, вы можете
захотеть, чтобы для вашего модуля, используемого по умолчанию,
тоже использовалось свое пространство имен (по умолчанию для
этого модуля оно не используется). Начиная с
версии 1.5.0, вы можете устанавливать параметр
// Через фронт-контроллер:
$front->setParam('prefixDefaultModule', true);
// Через диспетчер:
$dispatcher->setParam('prefixDefaultModule', true);
Это позволяет повторно использовать существующий модуль в качестве используемого по умолчанию в вашем приложении. |
Диспетчеризация производится циклически во фронт-контроллере. До того, как будет запущен процесс диспетчеризации, фронт-контроллер выполняет маршрутизацию запроса для нахождения пользовательских значений модуля, контроллера, действия и необязательных параметров. Затем он входит в цикл диспетчеризации, обрабатывая запрос.
В начале каждой итерации цикла он устанавливает флаг в объекте запроса, означающий, что действие было запущено. Если действие или методы pre/postDispatch установленного плагина сбросят этот флаг, то цикл диспетчеризации продолжится и будет произведена попытка обработать новый запрос. Изменяя контроллер и/или действие в запросе и сбрасывая флаг диспетчеризации, разработчик может задавать цепочку запросов для обработки.
Метод действия в контроллере, который таким образом управляет
диспетчеризацией, называется _forward(); вызывайте
этот метод из любых методов pre/postDispatch() или методов действий,
указывая действие, контроллер, модуль и опционально любые
дополнительные параметры, которые хотите передать новому
действию.
public function fooAction()
{
// переход к другому действию в текущем контроллере и модуле:
$this->_forward('bar', null, null, array('baz' => 'bogus'));
}
public function barAction()
{
// переход к действию в другом контроллере FooController::bazAction()
// в текущем модуле:
$this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
}
public function bazAction()
{
// переход к действию в другом контроллере в другом модуле
// Foo_BarController::bazAction():
$this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
}
Zend_Controller_Front сначала вызывает
маршрутизатор для получения первого действия в запросе. Затем он
входит в цикл диспетчеризации, в котором вызывается диспетчер для
запуска действия.
Диспетчеру для своей работы требуются различные данные - ему нужно "знать", как формировать имена контроллеров и действий, где искать файлы классов контроллеров, является ли допустимым или нет предоставленное имя модуля, и API для определения на основе другой доступной информации того, возможна ли диспетчеризация данного запроса.
Zend_Controller_Dispatcher_Interface определяет
следующие методы, которые требуется использовать во всех реализациях
диспетчера:
interface Zend_Controller_Dispatcher_Interface
{
/**
* Формирует из данной строки имя класса контроллера.
*
* @param string $unformatted
* @return string
*/
public function formatControllerName($unformatted);
/**
* Формирует из данной строки имя метода действия.
*
* @param string $unformatted
* @return string
*/
public function formatActionName($unformatted);
/**
* Определяет, доступен ли для диспетчеризации запрос
*
* @param Zend_Controller_Request_Abstract $request
* @return boolean
*/
public function isDispatchable(Zend_Controller_Request_Abstract $request);
/**
* Устанавливает пользовательский параметр
* (через фронт-контроллер или для локального использования)
*
* @param string $name
* @param mixed $value
* @return Zend_Controller_Dispatcher_Interface
*/
public function setParam($name, $value);
/**
* Устанавливает массив пользовательских параметров
*
* @param array $params
* @return Zend_Controller_Dispatcher_Interface
*/
public function setParams(array $params);
/**
* Возвращает один пользовательский параметр
*
* @param string $name
* @return mixed
*/
public function getParam($name);
/**
* Возвращает все пользовательские параметры
*
* @return array
*/
public function getParams();
/**
* Очищает весь стек пользовательских параметров
* или удаляет один пользовательский параметр
*
* @param null|string|array один ключ или массив ключей для удаления
* @return Zend_Controller_Dispatcher_Interface
*/
public function clearParams($name = null);
/**
* Устанавливает объект ответа для использования, если есть
*
* @param Zend_Controller_Response_Abstract|null $response
* @return void
*/
public function setResponse(Zend_Controller_Response_Abstract $response = null);
/**
* Возвращает объект ответа, если есть
*
* @return Zend_Controller_Response_Abstract|null
*/
public function getResponse();
/**
* Добавляет директорию в стек директорий контроллеров
*
* @param string $path
* @param string $args
* @return Zend_Controller_Dispatcher_Interface
*/
public function addControllerDirectory($path, $args = null);
/**
* Устанавливает директорию(-ии), в которой хранятся файлы контроллеров
*
* @param string|array $dir
* @return Zend_Controller_Dispatcher_Interface
*/
public function setControllerDirectory($path);
/**
* Возвращает установленную в данное время директорию(-ии) для поиска
* файлов контроллеров
*
* @return array
*/
public function getControllerDirectory();
/**
* Направляет запрос (модулю/)контроллеру/действию.
*
* @param Zend_Controller_Request_Abstract $request
* @param Zend_Controller_Response_Abstract $response
* @return Zend_Controller_Request_Abstract|boolean
*/
public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response);
/**
* Валиден или нет данный модуль
*
* @param string $module
* @return boolean
*/
public function isValidModule($module);
/**
* Возвращает используемое по умолчанию имя модуля
*
* @return string
*/
public function getDefaultModule();
/**
* Возвращает используемое по умолчанию имя контроллера
*
* @return string
*/
public function getDefaultControllerName();
/**
* Возвращает имя используемого по умолчанию действия
*
* @return string
*/
public function getDefaultAction();
}
Однако в большинстве случаев вам достаточно будет только расширить
абстрактный класс Zend_Controller_Dispatcher_Abstract,
в котором уже определены все эти методы или класс
Zend_Controller_Dispatcher_Standard для изменения
функционала стандартного диспетчера.
Основаниями для создания подклассов диспетчера могут быть желание использовать иную схему именования в своих контроллерах действий, либо другую парадигму диспетчеризации - например, файлы действий в директориях контроллеров вместо методов действий в классах контроллеров.



![[Замечание]](images/note.png)