TigerZF
🌐Español

24.3. El Controlador Frontal

24.3.1. Resumen

Zend_Controller_Front implementa un patrón de Controlador Frontal utilizado en aplicaciones Modelo-Vista-Controlador (MVC). Su propósito es inicializar el entorno de la petición, enrutar la petición entrante y luego despachar cualquier acción descubierta; agrega todas las respuestas y las devuelve cuando el proceso ha finalizado.

Zend_Controller_Front también implementa el patrón Singleton, lo que significa que solo una instancia de él puede estar disponible en un momento dado. Esto le permite actuar también como un registro sobre el que pueden apoyarse los demás objetos del proceso de despacho.

Zend_Controller_Front registra un agente de plugins (broker) consigo mismo, lo que permite que varios eventos que dispara sean observados por plugins. En la mayoría de los casos, esto brinda al desarrollador la oportunidad de adaptar el proceso de despacho al sitio sin necesidad de extender el controlador frontal para añadir funcionalidad.

Como mínimo, el controlador frontal necesita una o más rutas a directorios que contengan controladores de acción para realizar su trabajo. También se pueden invocar diversos métodos para adaptar aún más el entorno del controlador frontal y el de sus clases auxiliares.

[Note] Comportamiento por defecto

Por defecto, el controlador frontal carga el plugin ErrorHandler, así como el plugin auxiliar de acción ViewRenderer. Estos existen para simplificar, respectivamente, el manejo de errores y la renderización de vistas en sus controladores.

Para deshabilitar el ErrorHandler, realice lo siguiente en cualquier momento antes de llamar a dispatch():

// Disable the ErrorHandler plugin:
$front->setParam('noErrorHandler', true);

Para deshabilitar el ViewRenderer, haga lo siguiente antes de llamar a dispatch():

// Disable the ViewRenderer helper:
$front->setParam('noViewRenderer', true);

24.3.2. Métodos principales

El controlador frontal cuenta con varios accesores para configurar su entorno. Sin embargo, hay tres métodos principales clave para la funcionalidad del controlador frontal:

24.3.2.1. getInstance()

getInstance() se utiliza para obtener una instancia del controlador frontal. Dado que el controlador frontal implementa un patrón Singleton, este es también el único medio posible para instanciar un objeto de controlador frontal.

$front = Zend_Controller_Front::getInstance();

24.3.2.2. setControllerDirectory() y addControllerDirectory

setControllerDirectory() se utiliza para indicarle a al despachador dónde buscar los archivos de clase de controlador de acción. Acepta una única ruta o un array asociativo de pares de módulo y ruta.

Algunos ejemplos:

// Set the default controller directory:
$front->setControllerDirectory('../application/controllers');

// Set several module directories at once:
$front->setControllerDirectory(array(
    'default' => '../application/controllers',
    'blog'    => '../modules/blog/controllers',
    'news'    => '../modules/news/controllers',
));

// Add a 'foo' module directory:
$front->addControllerDirectory('../modules/foo/controllers', 'foo');
[Note] Nota

Si utiliza addControllerDirectory() sin un nombre de módulo, establecerá el directorio para el módulo default -- sobrescribiéndolo si ya existe.

Puede obtener la configuración actual del directorio de controladores utilizando getControllerDirectory(); esto devolverá un array de pares de módulo y directorio.

24.3.2.3. addModuleDirectory() y getModuleDirectory()

Un aspecto del controlador frontal es que puede definir una estructura de directorios modular para crear componentes independientes; estos se denominan "módulos".

Cada módulo debe estar en su propio directorio y reflejar la estructura de directorios del módulo por defecto -- es decir, debe tener como mínimo un subdirectorio /controllers/, y típicamente un subdirectorio /views/ y otros subdirectorios de la aplicación.

addModuleDirectory() le permite pasar el nombre de un directorio que contiene uno o más directorios de módulos. Luego lo escanea y los añade como directorios de controladores al controlador frontal.

Más adelante, si desea determinar la ruta a un módulo en particular o al módulo actual, puede llamar a getModuleDirectory(), pasando opcionalmente un nombre de módulo para obtener ese directorio de módulo específico.

24.3.2.4. dispatch()

dispatch(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null) realiza el trabajo pesado del controlador frontal. Puede opcionalmente recibir un objeto de petición y/o un objeto de respuesta, lo que permite al desarrollador pasar objetos personalizados para cada uno.

Si no se pasa ningún objeto de petición o respuesta, dispatch() comprobará si hay objetos registrados previamente y los usará, o instanciará versiones por defecto para usar en su proceso (en ambos casos, se usará por defecto la variante HTTP).

De manera similar, dispatch() comprueba si hay objetos enrutador y despachador registrados, instanciando las versiones por defecto de cada uno si no se encuentra ninguno.

El proceso de despacho tiene tres eventos distintos:

  • Enrutamiento

  • Despacho

  • Respuesta

El enrutamiento se produce exactamente una vez, utilizando los valores del objeto de petición cuando se llama a dispatch(). El despacho se produce en un bucle; una petición puede indicar múltiples acciones a despachar, o el controlador o un plugin puede restablecer el objeto de petición para forzar el despacho de acciones adicionales. Cuando todo ha terminado, el controlador frontal devuelve una respuesta.

24.3.2.5. run()

Zend_Controller_Front::run($path) es un método estático que simplemente recibe una ruta a un directorio que contiene controladores. Obtiene una instancia del controlador frontal (mediante getInstance()), registra la ruta proporcionada a través de setControllerDirectory(), y finalmente despacha.

Básicamente, run() es un método de conveniencia que puede usarse para configuraciones de sitio que no requieren personalización del entorno del controlador frontal.

// Instantiate front controller, set controller directory, and dispatch in one
// easy step:
Zend_Controller_Front::run('../application/controllers');

24.3.3. Métodos de acceso al entorno

Además de los métodos indicados anteriormente, existen varios métodos de acceso que pueden usarse para influir en el entorno del controlador frontal -- y por tanto en el entorno de las clases a las que el controlador frontal delega.

  • resetInstance() puede utilizarse para borrar toda la configuración actual. Su propósito principal es para pruebas, pero también puede usarse en casos en los que se desee encadenar varios controladores frontales.

  • setDefaultControllerName() y getDefaultControllerName() le permiten especificar un nombre diferente para usar como controlador por defecto (de lo contrario se usa 'index') y recuperar el valor actual. Actúan como proxy hacia el despachador.

  • setDefaultAction() y getDefaultAction() le permiten especificar un nombre diferente para usar como acción por defecto (de lo contrario se usa 'index') y recuperar el valor actual. Actúan como proxy hacia el despachador.

  • setRequest() y getRequest() le permiten especificar la petición (la clase u objeto) a usar durante el proceso de despacho y recuperar el objeto actual. Al establecer el objeto de petición, puede pasar el nombre de una clase de petición, en cuyo caso el método cargará el archivo de clase y la instanciará.

  • setRouter() getRouter() le permiten especificar el enrutador (la clase u objeto) a usar durante el proceso de despacho y recuperar el objeto actual. Al establecer el objeto enrutador, puede pasar el nombre de una clase de enrutador, en cuyo caso el método cargará el archivo de clase y la instanciará.

    Al recuperar el objeto enrutador, primero comprueba si hay uno presente, y si no, instancia el enrutador por defecto (el enrutador de reescritura).

  • setBaseUrl() y getBaseUrl() le permiten especificar la URL base a eliminar al enrutar peticiones y recuperar el valor actual. El valor se proporciona al objeto de petición justo antes de enrutar.

    [Note] No se admite una URL completamente calificada

    No se admite pasar una URL completamente calificada (por ejemplo: http://example.com/) al método setBaseUrl, y provocará problemas al usar el helper de vista de URL. Consulte el ticket ZF-10923 para más detalles.

  • setDispatcher() y getDispatcher() le permiten especificar el despachador (la clase u objeto) a usar durante el proceso de despacho y recuperar el objeto actual. Al establecer el objeto despachador, puede pasar el nombre de una clase de despachador, en cuyo caso el método cargará el archivo de clase y lo instanciará.

    Al recuperar el objeto despachador, primero comprueba si hay uno presente, y si no, instancia el despachador por defecto.

  • setResponse() y getResponse() le permiten especificar la respuesta (la clase u objeto) a usar durante el proceso de despacho y recuperar el objeto actual. Al establecer el objeto de respuesta, puede pasar el nombre de una clase de respuesta, en cuyo caso el método cargará el archivo de clase y la instanciará.

  • registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null) le permite registrar objetos plugin. Estableciendo el $stackIndex opcional, puede controlar el orden en el que se ejecutarán los plugins.

  • unregisterPlugin($plugin) le permite eliminar el registro de objetos plugin. $plugin puede ser un objeto plugin o una cadena que indique la clase del plugin a eliminar del registro.

  • throwExceptions($flag) se utiliza para activar/desactivar la capacidad de lanzar excepciones durante el proceso de despacho. Por defecto, las excepciones se capturan y se colocan en el objeto de respuesta; activar throwExceptions() anulará este comportamiento.

    Para más información, lea Excepciones del MVC.

  • returnResponse($flag) se utiliza para indicar al controlador frontal si debe devolver la respuesta (TRUE) desde dispatch(), o si la respuesta debe emitirse automáticamente (FALSE). Por defecto, la respuesta se emite automáticamente (llamando a Zend_Controller_Response_Abstract::sendResponse()); activar returnResponse() anulará este comportamiento.

    Entre las razones para devolver la respuesta se incluyen el deseo de comprobar excepciones antes de emitir la respuesta, la necesidad de registrar varios aspectos de la respuesta (como las cabeceras), etc.

24.3.4. Parámetros del controlador frontal

En la introducción, indicamos que el controlador frontal también actúa como un registro para los diversos componentes del controlador. Lo hace a través de una familia de métodos "param". Estos métodos le permiten registrar datos arbitrarios -- objetos y variables -- en el controlador frontal para recuperarlos en cualquier momento de la cadena de despacho. Estos valores se pasan al enrutador, al despachador y a los controladores de acción. Los métodos incluyen:

  • setParam($name, $value) le permite establecer un único parámetro de $name con el valor $value.

  • setParams(array $params) le permite establecer varios parámetros a la vez usando un array asociativo.

  • getParam($name) le permite recuperar un único parámetro a la vez, usando $name como el identificador.

  • getParams() le permite recuperar la lista completa de parámetros a la vez.

  • clearParams() le permite borrar un único parámetro (pasando un identificador de cadena), varios parámetros nombrados (pasando un array de identificadores de cadena), o la pila completa de parámetros (sin pasar nada).

Existen varios parámetros predefinidos que pueden establecerse y que tienen usos específicos en la cadena de despacho:

  • useDefaultControllerAlways se utiliza como indicación para el despachador para que use el controlador por defecto en el módulo por defecto para cualquier petición que no sea despachable (es decir, el módulo, el controlador y/o la acción no existen). Por defecto, esto está desactivado.

    Consulte Excepciones del MVC que puede encontrar para información más detallada sobre el uso de esta configuración.

  • disableOutputBuffering se utiliza como indicación para el despachador de que no debe usar el búfer de salida para capturar la salida generada por los controladores de acción. Por defecto, el despachador captura cualquier salida y la añade al contenido del cuerpo del objeto de respuesta.

  • noViewRenderer se utiliza para deshabilitar el ViewRenderer. Establezca este parámetro a TRUE para deshabilitarlo.

  • noErrorHandler se utiliza para deshabilitar el plugin Error Handler. Establezca este parámetro a TRUE para deshabilitarlo.

24.3.5. Extender el controlador frontal

Para extender el Controlador Frontal, como mínimo necesitará sobrescribir el método getInstance():

class My_Controller_Front extends Zend_Controller_Front
{
    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}

Sobrescribir el método getInstance() asegura que las llamadas posteriores a Zend_Controller_Front::getInstance() devolverán una instancia de su nueva subclase en lugar de una instancia de Zend_Controller_Front -- esto resulta particularmente útil para algunos de los enrutadores alternativos y helpers de vista.

Normalmente, no necesitará crear una subclase del controlador frontal a menos que necesite añadir nueva funcionalidad (por ejemplo, un autocargador de plugins, o una forma de especificar rutas de helpers de acción). Algunos puntos donde podría querer modificar el comportamiento incluyen cambiar cómo se almacenan los directorios de controladores, o qué enrutador o despachador se usan por defecto.