Zend_Controller_Front
implementa un Front Controller pattern usado en aplicaciones Model-View-Controller (MVC) . Su propósito es
inicializar el entorno de la solicitud, rutear la solicitud
entrante, y luego hacer un envío de cualquier de las acciones
descubiertas; le agrega las respuestas y las regresa cuando se
completa el proceso.
Zend_Controller_Front
también implementa el
Singleton pattern , significando que solo una única
instancia de él puede estar disponible en cualquier momento dado.
Esto le permite actuar también como un registro en el que los demás
objetos pueden extraer del proceso dispatch.
Zend_Controller_Front
registra un plugin broker consigo
mismo, permitiendo que diversos eventos que dispara sean observados
por plugins. En muchos casos, esto da el desarrollador la
oportunidad de adaptar el proceso de dispatch al sitio sin la
necesidad de ampliar el Front Controller para añadir funcionalidad.
Como mínimo, el front controller necesita una o más paths a directorios que contengan action controllers a fin de hacer su trabajo. Una variedad de métodos también pueden ser invocados para seguir adaptando el medio ambiente del front controller y ese a sus helper classes.
Comportamiento por Defecto
Por defecto, el front controller carga el ErrorHandler plugin, así como al ViewRenderer action helper plugin. Estos son para simplificar el manejo de errores y el view renderering en sus controladores, respectivamente.
Para deshabilitar el ErrorHandler ,
ejecutar lo siguiente en cualquier momento antes de llamar a
dispatch()
:
// Deshabilitar el ErrorHandler plugin: $front->setParam('noErrorHandler', true);
Para deshabilitar el ViewRenderer , haga
lo siguiente antes de llamar a
dispatch()
:
// Deshabilitar el ViewRenderer helper: $front->setParam('noViewRenderer', true);
El front controller tiene varios accessors para establecer su medio ambiente. Sin embargo, hay tres métodos básicos clave para la funcionalidad del front controller:
getInstance()
se utiliza para recuperar
una instancia del front controller. Como el front controller
implementa un patrón Singleton, este también es el único medio
posible para instanciar un objeto front controller.
$front = Zend_Controller_Front::getInstance();
setControllerDirectory()
se usa para
decirle a el
dispatcher dónde buscar para los archivos de clase
action
controller . Acepta bien un único path o un array
asociativo de pares módulo/path.
Como algunos ejemplos:
// Establer el directorio de controladores por defecto: $front->setControllerDirectory('../application/controllers'); // Establecer varios directorios módulos a la vez: $front->setControllerDirectory(array( 'default' => '../application/controllers', 'blog' => '../modules/blog/controllers', 'news' => '../modules/news/controllers', )); // Agregar un directorio de módulos 'foo': $front->addControllerDirectory('../modules/foo/controllers', 'foo');
Nota
Si usa addControllerDirectory()
sin un nombre de módulo, este establecerá el directorio
default para el módulo --
sobreescribiéndolo si ya existe.
Puede conseguir la configuración actual para el directorio
del controlador utilizando
getControllerDirectory()
; este
devolverá un array de pares módulo y directorio.
Uno de los aspectos del front controller es que puede definir una estructura modular de directorio para crear componentes standalone; estos son llamados "módulos".
Cada módulo debe estar en su propio directorio y ser un
espejo de la estructura del directorio del módulo por defecto --
es decir, que debería tener como mínimo un subdirectorio de
/controllers/
, y típicamente un
subdirectorio de /views/
y otros
subdirectorios de aplicaciones.
addModuleDirectory()
permite pasar el
nombre de un directorio que contiene uno o más directorios de
módulos. A continuación lo analiza y los añade como directorios
de controladores al front controller.
Después, si quiere determinar el path a un determinado módulo
o al módulo actual, puede llamar a
getModuleDirectory()
,
opcionalmente puede pasar un nombre de módulo para conseguir el
directorio de ese módulo específico.
dispatch(Zend_Controller_Request_Abstract $request =
null, Zend_Controller_Response_Abstract $response =
null)
hace el trabajo pesado del front
controller. Puede opcionalmente tomar un request object y/o
un response
object , permitiendo al desarrollador pasar objetos
peronalizados para cada uno.
Si no se pasa ningun objeto solicitud o respuesta,
dispatch()
comprobará por objetos
previamente registrados y utilizará esos o instanciará versiones
por defecto a utilizar en su proceso (en ambos casos, el sabor
de HTTP será utilizado por defecto).
Similarmente, dispatch()
comprueba
los objetos registrados router y dispatcher , instanciando las versiones por defecto
de cada uno si ninguno de ellos se encuentra.
El proceso de dispatch tiene tres eventos distintos:
-
Routing
-
Dispatching
-
Response
El routing se lleva a cabo exactamente una vez, utilizando
los valores del objeto solicitud cuando se llama a
dispatch()
. El dispatching se
lleva a cabo en un bucle; una solicitud puede indicar, bien
múltiples acciones de dispatch, o el controlador o un plugin
pueden restablecer el objeto solicitud para forzar medidas
adicionales para dispatch. Cuando todo está hecho, el front
controller devuelve una respuesta.
Zend_Controller_Front::run($path)
es un
método estático que toma simplemente un path a un directorio que
contiene controladores. Obtiene una instancia del front
controller (via getInstance() , registra el path provisto via setControllerDirectory() , y finalmente dispatches .
Básicamente, run()
es un método
conveniente que pueden utilizarse para setups de sitios que no
requieran la personalización del medio ambiente del front
controller.
// Instanciar el front controller, establecer el directorio de controladores, // y hacer el dispatch fácilmente en en un solo paso: Zend_Controller_Front::run('../application/controllers');
Además de los métodos enumerados anteriormente, hay una serie de métodos accessor que pueden utilizarse para afectar el entorno del front controller -- y por lo tanto el ambiente de las clases a las cuales delega el front controller.
-
resetInstance()
puede ser utilizada para borrar todos los settings actuales. Su objetivo principal es para testing, pero también puede ser utilizada para instancias donde desee encadenar múltiples front controllers. -
(set|get)DefaultControllerName()
permite especificar un nombre diferente para usar en el controlador por defecto (en caso coontrario, se usa 'index') y recuperar el valor actual. Delegan a el dispatcher . -
setDefaultAction()
ygetDefaultAction()
le deja especificar un nombre diferente a utilizar para la acción predeterminada (en caso coontrario, se usa 'index') y recuperar el valor actual. Delegan a el dispatcher . -
setRequest()
ygetRequest()
le permite especificar la clase u objeto el request a usar durante el proceso de dispatch y recuperar el objeto actual. Al setear el objeto solicitud, puede pasarlo en un nombre de clase de solicitud, en cuyo caso el método va a cargar el archivo clase y lo instanciará. -
setRouter()
getRouter()
le permite especificar la clase u objeto el router a usar durante el proceso de dispatch y recuperar el objeto actual. Al setear el objeto router, puede pasarlo en un nombre de clase de router, en cuyo caso el método va a cargar el archivo clase y lo instanciará.Al recuperar el objeto router, en primer lugar comprueba para ver si hay alguno presente, y si no, instancia al router por defecto(reescribe el router).
-
setBaseUrl()
ygetBaseUrl()
le permite especificar la URL base de la cual tirar cuando se rutean peticiones y recuperar el valor actual. El valor se provee al objeto solicitud justo antes de rutear. -
setDispatcher()
ygetDispatcher()
le permite especificar la clase u objeto el dispatcher a usar durante el proceso de dispatch y recuperar el objeto actual. Al setear el objeto dispatch, puede pasarlo en un nombre de clase de dispatcher, en cuyo caso el método va a cargar el archivo clase y lo instanciará.Al recuperar el objeto dispatch, en primer lugar comprueba para ver si hay alguno presente, y si no, instancia al dispatcher por defecto.
-
setResponse()
ygetResponse()
le permite especificar la clase u objeto response a usar durante el proceso de dispatch y recuperar el objeto actual. Al setear el objeto response, puede pasarlo en un nombre de clase de response, en cuyo caso el método va a cargar el archivo clase y lo instanciará. -
registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null)
le permite registrar plugin objects . Opcionalmente, setting$stackIndex
, puede controlar el orden en que se ejecutarán los plugins. -
unregisterPlugin($plugin)
le permite desregistrar plugin objects .$plugin
puede ser tanto un objeto plugin o un string que denota la clase de plugin a desregistrar. -
throwExceptions($flag)
se utiliza para activar o desactivar la capacidad de arrojar excepciones durante el proceso de dispatch. Por defecto, las excepciones son capturadas y colocadas en el objeto response ; activandothrowExceptions()
se anulará este comportamiento.Para más información, lea “Excepciones MVC” MVC Exceptions
-
returnResponse($flag)
se usa para decirle al front controller cuando regresar la respuesta (TRUE
) desdedispatch()
, o si la respuesta debe ser emitida automáticamente (FALSE
). Por defecto, la respuesta es automáticamente emitida (llamando aZend_Controller_Response_Abstract::sendResponse()
); activandoreturnResponse()
) se anulará este comportamiento.Las razones para regresar la respuesta incluyen un deseo de comprobar las excepciones antes de emitir la respuesta, necesidad de hacer un log de diversos aspectos de la respuesta (tales como cabeceras), etc.
En la introducción, se indicó que el front controller también actúa como un registro de los distintos componentes del controlador. Lo hace mediante una familia de métodos "param". Estos métodos le permiten registrar datos arbitrarios -- objetos y variables -- con el front controller, a ser devueltos en cualquier momento en la cadena de dispatch. Estos valores se transmiten al router, al dispatcher, y a los action controllers. Los métodos incluyen:
-
setParam($name, $value)
permite establecer un único parámetro de$name
con el valor$value
. -
setParams(array $params)
permite configurar varios parámetros a la vez usando un array asociativo. -
getParam($name)
permite recuperar un único parámetro a la vez, utilizando como identificador a$name
. -
getParams()
permite recuperar toda la lista de parámetros a la vez. -
clearParams()
permite borrar un único parámetro (pasando un string identificador), parámetros con múltiples nombres (pasando un array de strings identificadores), o el stack de parámetros completo (pasando nada).
Hay varios parámetros pre-definidos que puede ser seteados para tener usos específicos en la cadena de dispatch:
-
useDefaultControllerAlways se usa para indicar a el dispatcher que utilice el controlador por defecto en el módulo por defecto de cualquier solicitud que no sea dispatchable (es decir, el módulo, el controlador y/o la acción no existen). Por defecto, está en off.
Ver MVC Exceptions You May Encounter para información más detallada sobre el uso de este setting.
-
disableOutputBuffering se usa para indicarle a el dispatcher que no debe utilizar output buffering para capturar la salida generada por los controladores de acción. Por defecto, el dispatcher captura cualquier salida y la añade al contenido del cuerpo del objeto respuesta.
-
noViewRenderer se usa para deshabilitar el ViewRenderer . Poniendo este parámetro a true, lo deshabilita.
-
noErrorHandler se usa para deshabilitar el Error Handler plugin . Poniendo este parámetro a true, lo deshabilita.
Para extender el Front Controller, como mínimo que necesitará
anular 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; } }
Anulando el método getInstance()
asegura
que las subsiguientes llamadas a
Zend_Controller_Front::getInstance()
devolverá una instancia de su nueva subclase en lugar de una
instancia Zend_Controller_Front
-- esto es
particularmente útil para algunos de los routers alternativos y view
helpers.
Típicamente, no necesitará una subclase del front controller a menos que necesite añadir nuevas funcionalidades (por ejemplo, un plugin autoloader, o una forma de especificar los paths de los action helpers). Algunos de los puntos donde puede querer modificar el comportamiento puede incluir modificar cómo son almacenados los directorios de controladores , o qué router predeterminado o dispatcher se utiliza.