TigerZF
🌐Español

24.6. El despachador

24.6.1. Resumen

El despachado (dispatching) es el proceso de tomar el objeto de petición, Zend_Controller_Request_Abstract, extrayendo el nombre del módulo, el nombre del controlador, el nombre de la acción, y los parámetros opcionales contenidos en él, y luego instanciando un controlador y llamando a una acción de ese controlador. Si no se encuentra alguno de los valores de módulo, controlador o acción, se usarán valores predeterminados para ellos. Zend_Controller_Dispatcher_Standard especifica index para cada uno de los valores predeterminados de controlador y acción y default para el valor predeterminado del módulo, pero permite al desarrollador cambiar los valores predeterminados de cada uno usando los métodos setDefaultController(), setDefaultAction(), y setDefaultModule(), respectivamente.

[Note] Módulo predeterminado

Al crear aplicaciones modulares, puede que quiera que su módulo predeterminado también tenga espacio de nombres (la configuración predeterminada es que el módulo predeterminado no tenga espacio de nombres). A partir de 1.5.0, ahora puede hacerlo especificando prefixDefaultModule como TRUE en el controlador frontal o en su despachador:

// In your front controller:
$front->setParam('prefixDefaultModule', true);

// In your dispatcher:
$dispatcher->setParam('prefixDefaultModule', true);

Esto le permite reutilizar un módulo existente para que sea el módulo predeterminado de una aplicación.

El despachado ocurre en un bucle en el controlador frontal. Antes de que ocurra el despachado, el controlador frontal enruta la petición para encontrar los valores especificados por el usuario para el módulo, controlador, acción y los parámetros opcionales. Luego entra en un bucle de despachado, despachando la petición.

Al comienzo de cada iteración, establece un indicador en el objeto de petición indicando que la acción ha sido despachada. Si un plugin de acción o de pre o postDispatch restablece ese indicador, el bucle de despachado continuará e intentará despachar la nueva petición. Cambiando el controlador y/o la acción en la petición y restableciendo el indicador de despachado, el desarrollador puede definir una cadena de peticiones a realizar.

El método del controlador de acción que controla dicho despachado es _forward(); llame a este método desde cualquiera de los métodos preDispatch(), postDispatch() o de acción, proporcionando una acción, controlador, módulo, y opcionalmente cualquier parámetro adicional que desee enviar a la nueva acción:

public function fooAction()
{
    // forward to another action in the current controller and module:
    $this->_forward('bar', null, null, array('baz' => 'bogus'));
}

public function barAction()
{
    // forward to an action in another controller:
    // FooController::bazAction(),
    // in the current module:
    $this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
}

public function bazAction()
{
    // forward to an action in another controller in another module,
    // Foo_BarController::bazAction():
    $this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
}

24.6.2. Crear subclases del despachador

Zend_Controller_Front primero llamará al enrutador para determinar la primera acción en la petición. Luego entra en un bucle de despachado, que llama al despachador para despachar la acción.

El despachador necesita una variedad de datos para hacer su trabajo: necesita saber cómo formatear los nombres de controlador y acción, dónde buscar los archivos de clase del controlador, si un nombre de módulo proporcionado es válido o no, y una API para determinar si una petición dada es siquiera despachable en base a la otra información disponible.

Zend_Controller_Dispatcher_Interface define los siguientes métodos como requeridos para cualquier implementación de despachador:

interface Zend_Controller_Dispatcher_Interface
{
    /**
     * Format a string into a controller class name.
     *
     * @param string $unformatted
     * @return string
     */
    public function formatControllerName($unformatted);

    /**
     * Format a string into an action method name.
     *
     * @param string $unformatted
     * @return string
     */
    public function formatActionName($unformatted);

    /**
     * Determine if a request is dispatchable
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @return boolean
     */
    public function isDispatchable(
        Zend_Controller_Request_Abstract $request
    );

    /**
     * Set a user parameter (via front controller, or for local use)
     *
     * @param string $name
     * @param mixed $value
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function setParam($name, $value);

    /**
     * Set an array of user parameters
     *
     * @param array $params
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function setParams(array $params);

    /**
     * Retrieve a single user parameter
     *
     * @param string $name
     * @return mixed
     */
    public function getParam($name);

    /**
     * Retrieve all user parameters
     *
     * @return array
     */
    public function getParams();

    /**
     * Clear the user parameter stack, or a single user parameter
     *
     * @param null|string|array single key or array of keys for
     *        params to clear
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function clearParams($name = null);

    /**
     * Set the response object to use, if any
     *
     * @param Zend_Controller_Response_Abstract|null $response
     * @return void
     */
    public function setResponse(
        Zend_Controller_Response_Abstract $response = null
    );

    /**
     * Retrieve the response object, if any
     *
     * @return Zend_Controller_Response_Abstract|null
     */
    public function getResponse();

    /**
     * Add a controller directory to the controller directory stack
     *
     * @param string $path
     * @param string $args
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function addControllerDirectory($path, $args = null);

    /**
     * Set the directory (or directories) where controller files are
     * stored
     *
     * @param string|array $dir
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function setControllerDirectory($path);

    /**
     * Return the currently set directory(ies) for controller file
     * lookup
     *
     * @return array
     */
    public function getControllerDirectory();

    /**
     * Dispatch a request to a (module/)controller/action.
     *
     * @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
    );

    /**
     * Whether or not a given module is valid
     *
     * @param string $module
     * @return boolean
     */
    public function isValidModule($module);

    /**
     * Retrieve the default module name
     *
     * @return string
     */
    public function getDefaultModule();

    /**
     * Retrieve the default controller name
     *
     * @return string
     */
    public function getDefaultControllerName();

    /**
     * Retrieve the default action
     *
     * @return string
     */
    public function getDefaultAction();
}

En la mayoría de los casos, sin embargo, simplemente debería extender la clase abstracta Zend_Controller_Dispatcher_Abstract, en la cual cada uno de estos métodos ya han sido definidos, o Zend_Controller_Dispatcher_Standard para modificar la funcionalidad del despachador estándar.

Posibles razones para crear subclases del despachador incluyen el deseo de usar un esquema de nomenclatura de clases o métodos diferente en sus controladores de acción, o el deseo de usar un paradigma de despachado diferente, como despachar a archivos de acción bajo directorios de controlador (en lugar de despachar a métodos de clase).