Despachar es el proceso de tomar el objeto solicitud,
Zend_Controller_Request_Abstract
,
extraer el nombre del módulo, el nombre del controlador, el nombre
de la acción, y los
parámetros opcionales contenido en él, y luego
instanciar un controlador y llamar una
acción de ese controlador.
Si no se encuentra algún módulo, controlador o acción, se
usarán
los valores por defecto para ellos.
Zend_Controller_Dispatcher_Standard
especifica
index
para cada uno de los controladores y
acciones por defecto y
default
para el valor por
defecto del módulo, pero permite al desarrollador cambiar los
valores
por defecto para cada uno usando los métodos
setDefaultController()
,
setDefaultAction()
, y
setDefaultModule()
respectivamente.
Módulo por Defecto
Cuando se crean aplicaciones modulares, puede encontrarse
queriendo también el
namespace por defecto del módulo (la
configuración por defecto es que el módulo por
defecto es
no
namespaced).
Como de 1.5.0, ahora puede hacerlo especificando el
prefixDefaultModule
como
TRUE
tanto en el
front controller como es su despachador:
// En su front controller: $front->setParam('prefixDefaultModule', true); // En su despachador: $dispatcher->setParam('prefixDefaultModule', true);
Esto le permite re-determinar un módulo existente para ser el módulo por defecto para una solicitud.
El proceso de despachar tiene lugar en un bucle en el front controller. Antes de llevarse a cabo el despacho, el front controller rutea la solicitud para encontrar valores especificados por el usuario para el módulo, controlador, acción, y los parámetros opcionales. A continuación entra en un loop de despacho, despachando la solicitud.
Al comienzo de cada iteración, establece un flag en el objeto solicitud indicando que la acción se ha despachado. Si una acción o un plugin pre o postDispatch resetea ese flag, el loop de despacho continuará e intentará despachar la nueva solicitud. Cambiando el controlador y/o la acción en la solicitud y reseteando el flag despachado, el desarrollador puede definir una cadena de peticiones a realizar.
El método del controlador de acción que controla ese despacho es
_forward()
; llamar a este método para cualquiera de los
pre/postDispatch() o métodos de acción,
proporcionando un
controlador de acciónes, módulo y, opcionalmente cualquier parámetro
adicional que desee enviar a la nueva acción:
public function fooAction() { // adelantar a otra acción en el controlador y módulo actuales: $this->_forward('bar', null, null, array('baz' => 'bogus')); } public function barAction() { // adelantar a una acción en otro controlador: // FooController::bazAction(), // en el módulo actual: $this->_forward('baz', 'foo', null, array('baz' => 'bogus')); } public function bazAction() { // adelantar a una acción en otro controlador en otro módulo, // Foo_BarController::bazAction(): $this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus')); }
Zend_Controller_Front
llamará en primer lugar
al router para determinar la primera acción en la solicitud.
A
continuación se entra en un loop de despacho, el cual llama al
despachador para despachar
la acción.
El despachador necesita de una variedad de datos a fin de hacer su trabajo - necesita saber cómo formatear los nombres del controlador y de la acción, dónde mirar para los archivos de clase del controlador, cuándo el nombre de un controlador provisto es válido o no, y una API para determinar si una determinada solicitud es incluso despachable basado en la otra información disponible.
Zend_Controller_Dispatcher_Interface
define los siguientes métodos como necesarios para cualquier
implementación de un
despachador:
interface Zend_Controller_Dispatcher_Interface { /** * Formatea un string dentro del nombre de clase del controlador. * * @param string $unformatted * @return string */ public function formatControllerName($unformatted); /** * Formatea un string dentro de un nombre de método de acción. * * @param string $unformatted * @return string */ public function formatActionName($unformatted); /** * Determina si la solicitud es despachable * * @param Zend_Controller_Request_Abstract $request * @return boolean */ public function isDispatchable( Zend_Controller_Request_Abstract $request ); /** * Establece un parámetro de usuario (via front controller, o para uso local) * * @param string $name * @param mixed $value * @return Zend_Controller_Dispatcher_Interface */ public function setParam($name, $value); /** * Establece un array de parámetros de usuario * * @param array $params * @return Zend_Controller_Dispatcher_Interface */ public function setParams(array $params); /** * Recupera un único parámetro de usuario * * @param string $name * @return mixed */ public function getParam($name); /** * Recupera todos los parámetros de usuario * * @return array */ public function getParams(); /** * Limpia el stack de parámetros de usuario, o un único parámetro de usuario * * @param null|string|array single key or array of keys for * params to clear * @return Zend_Controller_Dispatcher_Interface */ public function clearParams($name = null); /** * Establece el objeto respuesta a usar, si hubiera alguno * * @param Zend_Controller_Response_Abstract|null $response * @return void */ public function setResponse( Zend_Controller_Response_Abstract $response = null ); /** * Recupera el objeto respuesta, si hubiera alguno * * @return Zend_Controller_Response_Abstract|null */ public function getResponse(); /** * Agrega un directorio de controladoes al stack de directorios de controladores * * @param string $path * @param string $args * @return Zend_Controller_Dispatcher_Interface */ public function addControllerDirectory($path, $args = null); /** * Establece el directorio (o directorios) donde se almacenan los archivos * de controladoes * * @param string|array $dir * @return Zend_Controller_Dispatcher_Interface */ public function setControllerDirectory($path); /** * Regresa el directorio(s) actualmente establecido para el lookup de los * archivos de controladores * * @return array */ public function getControllerDirectory(); /** * Despacha una solicitud a una acción de (módulo/)controlador. * * @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 ); /** * Si un módulo dado es válido o no * * @param string $module * @return boolean */ public function isValidModule($module); /** * Recuperar el nombre por defecto del módulo * * @return string */ public function getDefaultModule(); /** * Recuperar el nombre por defecto del controlador * * @return string */ public function getDefaultControllerName(); /** * Recuperar la acción por defecto * * @return string */ public function getDefaultAction(); }
En muchos casos, sin embargo, simplemente debe extender la clase
abstracta
Zend_Controller_Dispatcher_Abstract
,
en el que cada uno de estas ya han sido definidas, o
Zend_Controller_Dispatcher_Standard
para modificar la funcionalidad del despachador estándar.
Las posibles razones para subclasear al despachador incluye un deseo de utilizar un esquema diferente para nombrar las clases o métodos en sus controladores de acción, o el deseo de utilizar otro paradigma de despacho como ser despachar los archivos de acción bajo directorios de controladores (en lugar de despacharlos a los métodos de clase).