| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 17175 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.controller.front">
- <title>El Front Controller</title>
- <sect2 id="zend.controller.front.overview">
- <title>Introducción</title>
- <para>
- <classname>Zend_Controller_Front</classname>
- implementa un
- <ulink url="http://www.martinfowler.com/eaaCatalog/frontController.html">Front Controller
- pattern</ulink>
- usado en aplicaciones
- <ulink url="http://en.wikipedia.org/wiki/Model-view-controller">Model-View-Controller
- (MVC)</ulink>
- . 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.
- </para>
- <para>
- <classname>Zend_Controller_Front</classname>
- también implementa el
- <ulink url="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton pattern</ulink>
- ,
- 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.
- </para>
- <para>
- <classname>Zend_Controller_Front</classname>
- registra un
- <link linkend="zend.controller.plugins">plugin broker</link>
- 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.
- </para>
- <para>
- Como mínimo, el front controller necesita una o más paths a directorios que contengan
- <link linkend="zend.controller.action"> action controllers</link>
- 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.
- </para>
- <note>
- <title>Comportamiento por Defecto</title>
- <para>
- Por defecto, el front controller carga el
- <link linkend="zend.controller.plugins.standard.errorhandler">ErrorHandler</link>
- plugin, así como al
- <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>
- action helper plugin. Estos son para simplificar el manejo
- de errores y el view
- renderering en sus controladores, respectivamente.
- </para>
- <para>
- Para deshabilitar el
- <emphasis>ErrorHandler</emphasis>
- , ejecutar lo siguiente en
- cualquier momento antes de llamar a
- <methodname>dispatch()</methodname>
- :
- </para>
- <programlisting language="php"><![CDATA[
- // Deshabilitar el ErrorHandler plugin:
- $front->setParam('noErrorHandler', true);
- ]]></programlisting>
- <para>
- Para deshabilitar el
- <emphasis>ViewRenderer</emphasis>
- , haga lo siguiente antes
- de llamar a
- <methodname>dispatch()</methodname>
- :
- </para>
- <programlisting language="php"><![CDATA[
- // Deshabilitar el ViewRenderer helper:
- $front->setParam('noViewRenderer', true);
- ]]></programlisting>
- </note>
- </sect2>
- <sect2 id="zend.controller.front.methods.primary">
- <title>Métodos Básicos</title>
- <para>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:</para>
- <sect3 id="zend.controller.front.methods.primary.getinstance">
- <title>getInstance()</title>
- <para>
- <methodname>getInstance()</methodname>
- 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.
- </para>
- <programlisting language="php"><![CDATA[
- $front = Zend_Controller_Front::getInstance();
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.setcontrollerdirectory">
- <title>setControllerDirectory() y addControllerDirectory</title>
- <para>
- <methodname>setControllerDirectory()</methodname>
- se usa para decirle a
- <link linkend="zend.controller.dispatcher">el dispatcher</link>
- dónde buscar para los
- archivos de clase
- <link linkend="zend.controller.action">action controller</link>
- .
- Acepta bien un único path o un array asociativo de pares módulo/path.
- </para>
- <para>Como algunos ejemplos:</para>
- <programlisting language="php"><![CDATA[
- // 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');
- ]]></programlisting>
- <note>
- <para>
- Si usa
- <methodname>addControllerDirectory()</methodname>
- sin un nombre de
- módulo, este establecerá el directorio
- <emphasis>default</emphasis>
- para el
- módulo -- sobreescribiéndolo si ya existe.
- </para>
- </note>
- <para>
- Puede conseguir la configuración actual para el directorio del controlador
- utilizando
- <methodname>getControllerDirectory()</methodname>
- ; este devolverá un
- array de pares módulo y directorio.
- </para>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.addmoduledirectory">
- <title>addModuleDirectory() y getModuleDirectory()</title>
- <para>
- Uno de los aspectos del front controller es que puede
- <link linkend="zend.controller.modular"> definir una estructura modular de
- directorio</link>
- para crear componentes standalone; estos son llamados
- "módulos".
- </para>
- <para>
- 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
- <filename>/controllers/</filename>
- , y típicamente un subdirectorio
- de
- <filename>/views/</filename>
- y otros subdirectorios de aplicaciones.
- </para>
- <para>
- <methodname>addModuleDirectory()</methodname>
- 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.
- </para>
- <para>
- Después, si quiere determinar el path a un determinado módulo o al módulo actual,
- puede llamar a
- <methodname>getModuleDirectory()</methodname>
- , opcionalmente puede
- pasar un nombre de módulo para conseguir el directorio de ese
- módulo específico.
- </para>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.dispatch">
- <title>dispatch()</title>
- <para>
- <methodname>dispatch(Zend_Controller_Request_Abstract $request = null,
- Zend_Controller_Response_Abstract $response = null)</methodname>
- hace el trabajo
- pesado del front controller. Puede opcionalmente tomar un
- <link linkend="zend.controller.request">request object</link>
- y/o un
- <link linkend="zend.controller.response">response object</link>
- , permitiendo al
- desarrollador pasar objetos peronalizados para cada uno.
- </para>
- <para>
- Si no se pasa ningun objeto solicitud o respuesta,
- <methodname>dispatch()</methodname>
- comprobará por objetos previamente
- registrados y utilizará esos o instanciará
- versiones por defecto a utilizar en su
- proceso (en ambos casos, el sabor de
- <acronym>HTTP</acronym>
- será utilizado por
- defecto).
- </para>
- <para>
- Similarmente,
- <methodname>dispatch()</methodname>
- comprueba los objetos
- registrados
- <link linkend="zend.controller.router">router</link>
- y
- <link linkend="zend.controller.dispatcher">dispatcher</link>
- , instanciando las
- versiones por defecto de cada uno si ninguno de ellos se
- encuentra.
- </para>
- <para>El proceso de dispatch tiene tres eventos distintos:</para>
- <itemizedlist>
- <listitem>
- <para>Routing</para>
- </listitem>
- <listitem>
- <para>Dispatching</para>
- </listitem>
- <listitem>
- <para>Response</para>
- </listitem>
- </itemizedlist>
- <para>
- El routing se lleva a cabo exactamente una vez, utilizando los valores del objeto
- solicitud cuando se llama a
- <methodname>dispatch()</methodname>
- . 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.
- </para>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.run">
- <title>run()</title>
- <para>
- <methodname>Zend_Controller_Front::run($path)</methodname>
- es un método estático que
- toma simplemente un path a un directorio que contiene
- controladores. Obtiene una
- instancia del front controller (via
- <link linkend="zend.controller.front.methods.primary.getinstance">getInstance()</link>
- , registra el path provisto via
- <link linkend="zend.controller.front.methods.primary.setcontrollerdirectory">setControllerDirectory()</link>
- , y finalmente
- <link linkend="zend.controller.front.methods.primary.dispatch">dispatches</link>
- .
- </para>
- <para>
- Básicamente,
- <methodname>run()</methodname>
- es un método conveniente que pueden
- utilizarse para setups de sitios que no requieran
- la personalización del medio
- ambiente del front controller.
- </para>
- <programlisting language="php"><![CDATA[
- // 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');
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.controller.front.methods.environment">
- <title>Métodos Accessor Ambientales</title>
- <para>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.</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>resetInstance()</methodname>
- 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.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>(set|get)DefaultControllerName()</methodname>
- 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
- <link linkend="zend.controller.dispatcher">el dispatcher</link>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setDefaultAction()</methodname>
- y
- <methodname>getDefaultAction()</methodname>
- 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
- <link linkend="zend.controller.dispatcher">el dispatcher</link>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setRequest()</methodname>
- y
- <methodname>getRequest()</methodname>
- le
- permite especificar la clase u objeto
- <link linkend="zend.controller.request">el
- request</link>
- 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á.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setRouter()</methodname>
- <methodname>getRouter()</methodname>
- le permite especificar la clase u objeto
- <link linkend="zend.controller.router">el router</link>
- 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á.
- </para>
- <para>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).
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setBaseUrl()</methodname>
- y
- <methodname>getBaseUrl()</methodname>
- le
- permite especificar
- <link linkend="zend.controller.request.http.baseurl">la URL
- base</link>
- de la cual tirar cuando se rutean peticiones y recuperar el
- valor actual. El
- valor se provee al objeto solicitud justo antes de rutear.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setDispatcher()</methodname>
- y
- <methodname>getDispatcher()</methodname>
- le permite especificar la clase u
- objeto
- <link linkend="zend.controller.dispatcher">el dispatcher</link>
- 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á.
- </para>
- <para>Al recuperar el objeto dispatch, en primer lugar comprueba para ver si hay
- alguno presente, y si no, instancia al dispatcher por defecto.</para>
- </listitem>
- <listitem>
- <para>
- <methodname>setResponse()</methodname>
- y
- <methodname>getResponse()</methodname>
- le permite especificar la clase u objeto
- <link linkend="zend.controller.response">response</link>
- 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á.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex
- = null)</methodname>
- le permite registrar
- <link linkend="zend.controller.plugins">plugin objects</link>
- . Opcionalmente,
- setting
- <varname>$stackIndex</varname>
- , puede controlar el orden en que se
- ejecutarán los plugins.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>unregisterPlugin($plugin)</methodname>
- le permite desregistrar
- <link linkend="zend.controller.plugins">plugin objects</link>
- .
- <varname>$plugin</varname>
- puede ser tanto un objeto plugin o un string que
- denota la clase de plugin a
- desregistrar.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>throwExceptions($flag)</methodname>
- 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
- <link linkend="zend.controller.response">objeto response </link>
- ; activando
- <methodname>throwExceptions()</methodname>
- se anulará este comportamiento.
- </para>
- <para>
- Para más información, lea
- <xref linkend="zend.controller.exceptions"/>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>returnResponse($flag)</methodname>
- se usa para decirle al front
- controller cuando regresar la respuesta (
- <constant>TRUE</constant>
- ) desde
- <methodname>dispatch()</methodname>
- , o si la respuesta debe ser emitida
- automáticamente (
- <constant>FALSE</constant>
- ). Por defecto, la respuesta es
- automáticamente emitida (llamando a
- <methodname>Zend_Controller_Response_Abstract::sendResponse()</methodname>
- );
- activando
- <methodname>returnResponse()</methodname>
- ) se anulará este
- comportamiento.
- </para>
- <para>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.</para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.controller.front.methods.params">
- <title>Parámetros de Front Controller</title>
- <para>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:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setParam($name, $value)</methodname>
- permite establecer un único
- parámetro de
- <varname>$name</varname>
- con el valor
- <varname>$value</varname>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setParams(array $params)</methodname>
- permite configurar varios
- parámetros a la vez usando un array asociativo.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getParam($name)</methodname>
- permite recuperar un único parámetro a
- la vez, utilizando como identificador a
- <varname>$name</varname>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getParams()</methodname>
- permite recuperar toda la lista de
- parámetros a la vez.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearParams()</methodname>
- 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).
- </para>
- </listitem>
- </itemizedlist>
- <para>Hay varios parámetros pre-definidos que puede ser seteados para tener usos
- específicos
- en la cadena de dispatch:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>useDefaultControllerAlways</methodname>
- se usa para indicar a
- <link linkend="zend.controller.dispatcher">el dispatcher</link>
- 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.
- </para>
- <para>
- Ver
- <link linkend="zend.controller.exceptions.internal">MVC Exceptions You
- May Encounter</link>
- para información más detallada sobre el uso de este
- setting.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>disableOutputBuffering</methodname>
- se usa para indicarle a
- <link linkend="zend.controller.dispatcher">el dispatcher</link>
- 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.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>noViewRenderer</emphasis>
- se usa para deshabilitar el
- <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>
- .
- Poniendo este parámetro a true, lo deshabilita.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>noErrorHandler</emphasis>
- se usa para deshabilitar el
- <link linkend="zend.controller.plugins.standard.errorhandler">Error Handler
- plugin</link>
- . Poniendo este parámetro a true, lo deshabilita.
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.controller.front.subclassing">
- <title>Extendiendo el Front Controller</title>
- <para>
- Para extender el Front Controller, como mínimo que necesitará anular el método
- <methodname>getInstance()</methodname>
- :
- </para>
- <programlisting language="php"><![CDATA[
- class My_Controller_Front extends Zend_Controller_Front
- {
- public static function getInstance()
- {
- if (null === self::$_instance) {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
- }
- ]]></programlisting>
- <para>
- Anulando el método
- <methodname>getInstance()</methodname>
- asegura que las
- subsiguientes llamadas a
- <methodname>Zend_Controller_Front::getInstance()</methodname>
- devolverá una instancia de su nueva subclase en lugar de una instancia
- <classname>Zend_Controller_Front</classname>
- -- esto es particularmente útil para
- algunos de los routers alternativos y view helpers.
- </para>
- <para>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.</para>
- </sect2>
- </sect1>
|