Programmer's Reference Guide
| Стандартный маршрутизатор |
Диспетчер
Обзор
Диспетчеризация — это процесс принятия объекта запроса
(Zend_Controller_Request_Abstract), извлечения
содержащихся в нем имени модуля, имени контроллера, имени действия и
необязательных параметров, затем инстанцирования контроллера и
вызова действия в нем. Если не найдены модуль, контроллер или
действие, то будут использоваться значения по умолчанию.
Zend_Controller_Dispatcher_Standard определяет
index как значение по умолчанию для контроллера и
действия, и default - для модуля, но позволяет
разработчику изменять эти значения, используя
setDefaultController(),
setDefaultAction() и setDefaultModule(),
соответственно.
Замечание: Модуль, используемый по умолчанию
При создании приложения, состоящего из модулей, вы можете захотеть, чтобы для вашего модуля, используемого по умолчанию, тоже использовалось свое пространство имен (по умолчанию для этого модуля оно не используется). Начиная с версии 1.5.0, вы можете устанавливать параметрprefixDefaultModuleв true, используя фронт-контроллер или диспетчер.
Это позволяет повторно использовать существующий модуль в качестве используемого по умолчанию в вашем приложении.
// Через фронт-контроллер: $front->setParam('prefixDefaultModule', true); // Через диспетчер: $dispatcher->setParam('prefixDefaultModule', true);
Диспетчеризация производится циклически во фронт-контроллере. До того, как будет запущен процесс диспетчеризации, фронт-контроллер выполняет маршрутизацию запроса для нахождения пользовательских значений модуля, контроллера, действия и необязательных параметров. Затем он входит в цикл диспетчеризации, обрабатывая запрос.
В начале каждой итерации цикла он устанавливает флаг в объекте запроса, означающий, что действие было запущено. Если действие или методы pre/postDispatch установленного плагина сбросят этот флаг, то цикл диспетчеризации продолжится и будет произведена попытка обработать новый запрос. Изменяя контроллер и/или действие в запросе и сбрасывая флаг диспетчеризации, разработчик может задавать цепочку запросов для обработки.
Метод действия в контроллере, который таким образом управляет
диспетчеризацией, называется _forward(); вызывайте
этот метод из любых методов pre/postDispatch() или методов действий,
указывая действие, контроллер, модуль и опционально любые
дополнительные параметры, которые хотите передать новому
действию.
- public function fooAction()
- {
- // переход к другому действию в текущем контроллере и модуле:
- }
- public function barAction()
- {
- // переход к действию в другом контроллере FooController::bazAction()
- // в текущем модуле:
- }
- public function bazAction()
- {
- // переход к действию в другом контроллере в другом модуле
- // Foo_BarController::bazAction():
- }
Создание подклассов диспетчера
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
- */
- /**
- * Возвращает один пользовательский параметр
- *
- * @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 для изменения функционала стандартного диспетчера.
Основаниями для создания подклассов диспетчера могут быть желание использовать иную схему именования в своих контроллерах действий, либо другую парадигму диспетчеризации - например, файлы действий в директориях контроллеров вместо методов действий в классах контроллеров.
| Стандартный маршрутизатор |
Add A Comment
Please do not report issues via comments; use the ZF Issue Tracker.
If you have a JIRA/Crowd account, we suggest you login first before commenting.
Select a Version
Languages Available
Components
Search the Manual
Navigation
- Руководство разработчика
- Руководство разработчика
- Справочное руководство Zend Framework
- Zend_Controller
- Zend_Controller - Быстрый старт
- Основы Zend_Controller
- Фронт-контроллер
- Объект запроса
- Стандартный маршрутизатор
- Диспетчер
- Контроллеры действий
- Помощники действий
- Объект ответа
- Плагины
- Использование модульной структуры директорий
- Исключения

Comments
Thanks for the great intro!
it should read: "setDefaultControllerName()"
public function fooAction()
{
// forward to another action in the current controller and module:
$this->_forward('bar', null, null, array('baz' => 'bogus'));
}
When I tried to read the parameter:
public function barAction($baz);
{
$stuff = $baz['baz'];
// rest of code
}
I get:
Warning: Missing argument 1 for AccountController::barAction()...
What am I doing wrong?
public function barAction();
{
$stuff = $this->_getParam('baz');
// rest of code
}
public function fooAction() {
if (1==1) {
$this->_forward('footest'); // First forward
}
$this->_forward('foomore'); // Second forward
}
public function footestAction() {
echo 'foo testing'; exit;
}
public function foomoreAction() {
echo 'foo more'; exit;
}
The first forward always fails while the second forward works.
The output is "foo more" printing in the web page.
Can anyone know why it is not forwarding to footest?
the _forward method does not execute a return statement, it updates the $request object. In your example, the two calls of the _forward method are executed, but only the last one is used.
Check the source of the _forward method (in the Zend_Controller_Action class).
You must write this code instead to make it work :
public function fooAction() {
if (1==1) {
$this->_forward('footest'); // First forward
return; // <-- stop the execution of the fooAction now
}
$this->_forward('foomore'); // Second forward
}