Zend_Controller-FrontController.xml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 17175 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.controller.front">
  5. <title>El Front Controller</title>
  6. <sect2 id="zend.controller.front.overview">
  7. <title>Introducción</title>
  8. <para>
  9. <classname>Zend_Controller_Front</classname> implementa un <ulink
  10. url="http://www.martinfowler.com/eaaCatalog/frontController.html">Front Controller
  11. pattern</ulink> usado en aplicaciones <ulink
  12. url="http://en.wikipedia.org/wiki/Model-view-controller">Model-View-Controller
  13. (MVC)</ulink>. Su propósito es inicializar el entorno de la solicitud, rutear la
  14. solicitud entrante, y luego hacer un envío de cualquier de las acciones descubiertas; le
  15. agrega las respuestas y las regresa cuando se completa el proceso. </para>
  16. <para>
  17. <classname>Zend_Controller_Front</classname> también implementa el <ulink
  18. url="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton pattern</ulink>,
  19. significando que solo una única instancia de él puede estar disponible en cualquier
  20. momento dado. Esto le permite actuar también como un registro en el que los demás
  21. objetos pueden extraer del proceso dispatch. </para>
  22. <para>
  23. <classname>Zend_Controller_Front</classname> registra un <link
  24. linkend="zend.controller.plugins">plugin broker</link> consigo mismo, permitiendo
  25. que diversos eventos que dispara sean observados por plugins. En muchos casos, esto da
  26. el desarrollador la oportunidad de adaptar el proceso de dispatch al sitio sin la
  27. necesidad de ampliar el Front Controller para añadir funcionalidad. </para>
  28. <para> Como mínimo, el front controller necesita una o más paths a directorios que contengan
  29. <link linkend="zend.controller.action"> action controllers</link> a fin de hacer su
  30. trabajo. Una variedad de métodos también pueden ser invocados para seguir adaptando el
  31. medio ambiente del front controller y ese a sus helper classes. </para>
  32. <note>
  33. <title>Comportamiento por Defecto</title>
  34. <para> Por defecto, el front controller carga el <link
  35. linkend="zend.controller.plugins.standard.errorhandler">ErrorHandler</link>
  36. plugin, así como al <link linkend="zend.controller.actionhelpers.viewrenderer"
  37. >ViewRenderer</link> action helper plugin. Estos son para simplificar el manejo
  38. de errores y el view renderering en sus controladores, respectivamente. </para>
  39. <para> Para deshabilitar el <emphasis>ErrorHandler</emphasis>, ejecutar lo siguiente en
  40. cualquier momento antes de llamar a <methodname>dispatch()</methodname>: </para>
  41. <programlisting language="php"><![CDATA[
  42. // Deshabilitar el ErrorHandler plugin:
  43. $front->setParam('noErrorHandler', true);
  44. ]]></programlisting>
  45. <para> Para deshabilitar el <emphasis>ViewRenderer</emphasis>, haga lo siguiente antes
  46. de llamar a <methodname>dispatch()</methodname>: </para>
  47. <programlisting language="php"><![CDATA[
  48. // Deshabilitar el ViewRenderer helper:
  49. $front->setParam('noViewRenderer', true);
  50. ]]></programlisting>
  51. </note>
  52. </sect2>
  53. <sect2 id="zend.controller.front.methods.primary">
  54. <title>Métodos Básicos</title>
  55. <para> El front controller tiene varios accessors para establecer su medio ambiente. Sin
  56. embargo, hay tres métodos básicos clave para la funcionalidad del front controller: </para>
  57. <sect3 id="zend.controller.front.methods.primary.getinstance">
  58. <title>getInstance()</title>
  59. <para>
  60. <methodname>getInstance()</methodname> se utiliza para recuperar una instancia del
  61. front controller. Como el front controller implementa un patrón Singleton, este
  62. también es el único medio posible para instanciar un objeto front controller. </para>
  63. <programlisting language="php"><![CDATA[
  64. $front = Zend_Controller_Front::getInstance();
  65. ]]></programlisting>
  66. </sect3>
  67. <sect3 id="zend.controller.front.methods.primary.setcontrollerdirectory">
  68. <title>setControllerDirectory() y addControllerDirectory</title>
  69. <para>
  70. <methodname>setControllerDirectory()</methodname> se usa para decirle a <link
  71. linkend="zend.controller.dispatcher">el dispatcher</link> dónde buscar para los
  72. archivos de clase <link linkend="zend.controller.action">action controller</link>.
  73. Acepta bien un único path o un array asociativo de pares módulo/path. </para>
  74. <para> Como algunos ejemplos: </para>
  75. <programlisting language="php"><![CDATA[
  76. // Establer el directorio de controladores por defecto:
  77. $front->setControllerDirectory('../application/controllers');
  78. // Establecer varios directorios módulos a la vez:
  79. $front->setControllerDirectory(array(
  80. 'default' => '../application/controllers',
  81. 'blog' => '../modules/blog/controllers',
  82. 'news' => '../modules/news/controllers',
  83. ));
  84. // Agregar un directorio de módulos 'foo':
  85. $front->addControllerDirectory('../modules/foo/controllers', 'foo');
  86. ]]></programlisting>
  87. <note>
  88. <para> Si usa <methodname>addControllerDirectory()</methodname> sin un nombre de
  89. módulo, este establecerá el directorio <emphasis>default</emphasis> para el
  90. módulo -- sobreescribiéndolo si ya existe. </para>
  91. </note>
  92. <para> Puede conseguir la configuración actual para el directorio del controlador
  93. utilizando <methodname>getControllerDirectory()</methodname>; este devolverá un
  94. array de pares módulo y directorio. </para>
  95. </sect3>
  96. <sect3 id="zend.controller.front.methods.primary.addmoduledirectory">
  97. <title>addModuleDirectory() y getModuleDirectory()</title>
  98. <para> Uno de los aspectos del front controller es que puede <link
  99. linkend="zend.controller.modular"> definir una estructura modular de
  100. directorio</link> para crear componentes standalone; estos son llamados
  101. "módulos". </para>
  102. <para> Cada módulo debe estar en su propio directorio y ser un espejo de la estructura
  103. del directorio del módulo por defecto -- es decir, que debería tener como mínimo un
  104. subdirectorio de <filename>/controllers/</filename>, y típicamente un subdirectorio
  105. de <filename>/views/</filename> y otros subdirectorios de aplicaciones. </para>
  106. <para>
  107. <methodname>addModuleDirectory()</methodname> permite pasar el nombre de un
  108. directorio que contiene uno o más directorios de módulos. A continuación lo analiza
  109. y los añade como directorios de controladores al front controller. </para>
  110. <para> Después, si quiere determinar el path a un determinado módulo o al módulo actual,
  111. puede llamar a <methodname>getModuleDirectory()</methodname>, opcionalmente puede
  112. pasar un nombre de módulo para conseguir el directorio de ese módulo específico.
  113. </para>
  114. </sect3>
  115. <sect3 id="zend.controller.front.methods.primary.dispatch">
  116. <title>dispatch()</title>
  117. <para>
  118. <methodname>dispatch(Zend_Controller_Request_Abstract $request = null,
  119. Zend_Controller_Response_Abstract $response = null)</methodname> hace el trabajo
  120. pesado del front controller. Puede opcionalmente tomar un <link
  121. linkend="zend.controller.request">request object</link> y/o un <link
  122. linkend="zend.controller.response">response object</link>, permitiendo al
  123. desarrollador pasar objetos peronalizados para cada uno. </para>
  124. <para> Si no se pasa ningun objeto solicitud o respuesta,
  125. <methodname>dispatch()</methodname> comprobará por objetos previamente
  126. registrados y utilizará esos o instanciará versiones por defecto a utilizar en su
  127. proceso (en ambos casos, el sabor de <acronym>HTTP</acronym> será utilizado por
  128. defecto). </para>
  129. <para> Similarmente, <methodname>dispatch()</methodname> comprueba los objetos
  130. registrados <link linkend="zend.controller.router">router</link> y <link
  131. linkend="zend.controller.dispatcher">dispatcher</link> , instanciando las
  132. versiones por defecto de cada uno si ninguno de ellos se encuentra. </para>
  133. <para> El proceso de dispatch tiene tres eventos distintos: </para>
  134. <itemizedlist>
  135. <listitem>
  136. <para>Routing</para>
  137. </listitem>
  138. <listitem>
  139. <para>Dispatching</para>
  140. </listitem>
  141. <listitem>
  142. <para>Response</para>
  143. </listitem>
  144. </itemizedlist>
  145. <para> El routing se lleva a cabo exactamente una vez, utilizando los valores del objeto
  146. solicitud cuando se llama a <methodname>dispatch()</methodname>. El dispatching se
  147. lleva a cabo en un bucle; una solicitud puede indicar, bien múltiples acciones de
  148. dispatch, o el controlador o un plugin pueden restablecer el objeto solicitud para
  149. forzar medidas adicionales para dispatch. Cuando todo está hecho, el front
  150. controller devuelve una respuesta. </para>
  151. </sect3>
  152. <sect3 id="zend.controller.front.methods.primary.run">
  153. <title>run()</title>
  154. <para>
  155. <classname>Zend_Controller_Front::run($path)</classname> es un método estático que
  156. toma simplemente un path a un directorio que contiene controladores. Obtiene una
  157. instancia del front controller (via <link
  158. linkend="zend.controller.front.methods.primary.getinstance"
  159. >getInstance()</link>, registra el path provisto via <link
  160. linkend="zend.controller.front.methods.primary.setcontrollerdirectory"
  161. >setControllerDirectory()</link>, y finalmente <link
  162. linkend="zend.controller.front.methods.primary.dispatch">dispatches</link>. </para>
  163. <para> Básicamente, <methodname>run()</methodname> es un método conveniente que pueden
  164. utilizarse para setups de sitios que no requieran la personalización del medio
  165. ambiente del front controller. </para>
  166. <programlisting language="php"><![CDATA[
  167. // Instanciar el front controller, establecer el directorio de controladores,
  168. // y hacer el dispatch fácilmente en en un solo paso:
  169. Zend_Controller_Front::run('../application/controllers');
  170. ]]></programlisting>
  171. </sect3>
  172. </sect2>
  173. <sect2 id="zend.controller.front.methods.environment">
  174. <title>Métodos Accessor Ambientales</title>
  175. <para> Además de los métodos enumerados anteriormente, hay una serie de métodos accessor que
  176. pueden utilizarse para afectar el entorno del front controller -- y por lo tanto el
  177. ambiente de las clases a las cuales delega el front controller. </para>
  178. <itemizedlist>
  179. <listitem>
  180. <para>
  181. <methodname>resetInstance()</methodname> puede ser utilizada para borrar todos
  182. los settings actuales. Su objetivo principal es para testing, pero también puede
  183. ser utilizada para instancias donde desee encadenar múltiples front controllers.
  184. </para>
  185. </listitem>
  186. <listitem>
  187. <para>
  188. <methodname>(set|get)DefaultControllerName()</methodname> permite especificar un
  189. nombre diferente para usar en el controlador por defecto (en caso coontrario, se
  190. usa 'index') y recuperar el valor actual. Delegan a <link
  191. linkend="zend.controller.dispatcher">el dispatcher</link>. </para>
  192. </listitem>
  193. <listitem>
  194. <para>
  195. <methodname>setDefaultAction()</methodname> y
  196. <methodname>getDefaultAction()</methodname> le deja especificar un nombre
  197. diferente a utilizar para la acción predeterminada (en caso coontrario, se usa
  198. 'index') y recuperar el valor actual. Delegan a <link
  199. linkend="zend.controller.dispatcher">el dispatcher</link>. </para>
  200. </listitem>
  201. <listitem>
  202. <para>
  203. <methodname>setRequest()</methodname> y <methodname>getRequest()</methodname> le
  204. permite especificar la clase u objeto <link linkend="zend.controller.request">el
  205. request</link> a usar durante el proceso de dispatch y recuperar el objeto
  206. actual. Al setear el objeto solicitud, puede pasarlo en un nombre de clase de
  207. solicitud, en cuyo caso el método va a cargar el archivo clase y lo instanciará.
  208. </para>
  209. </listitem>
  210. <listitem>
  211. <para>
  212. <methodname>setRouter()</methodname>
  213. <methodname>getRouter()</methodname> le permite especificar la clase u objeto
  214. <link linkend="zend.controller.router">el router</link> a usar durante el
  215. proceso de dispatch y recuperar el objeto actual. Al setear el objeto router,
  216. puede pasarlo en un nombre de clase de router, en cuyo caso el método va a
  217. cargar el archivo clase y lo instanciará. </para>
  218. <para> Al recuperar el objeto router, en primer lugar comprueba para ver si hay
  219. alguno presente, y si no, instancia al router por defecto(reescribe el router).
  220. </para>
  221. </listitem>
  222. <listitem>
  223. <para>
  224. <methodname>setBaseUrl()</methodname> y <methodname>getBaseUrl()</methodname> le
  225. permite especificar <link linkend="zend.controller.request.http.baseurl">la URL
  226. base</link> de la cual tirar cuando se rutean peticiones y recuperar el
  227. valor actual. El valor se provee al objeto solicitud justo antes de rutear.
  228. </para>
  229. </listitem>
  230. <listitem>
  231. <para>
  232. <methodname>setDispatcher()</methodname> y
  233. <methodname>getDispatcher()</methodname> le permite especificar la clase u
  234. objeto <link linkend="zend.controller.dispatcher">el dispatcher</link> a usar
  235. durante el proceso de dispatch y recuperar el objeto actual. Al setear el objeto
  236. dispatch, puede pasarlo en un nombre de clase de dispatcher, en cuyo caso el
  237. método va a cargar el archivo clase y lo instanciará. </para>
  238. <para> Al recuperar el objeto dispatch, en primer lugar comprueba para ver si hay
  239. alguno presente, y si no, instancia al dispatcher por defecto. </para>
  240. </listitem>
  241. <listitem>
  242. <para>
  243. <methodname>setResponse()</methodname> y <methodname>getResponse()</methodname>
  244. le permite especificar la clase u objeto <link
  245. linkend="zend.controller.response">response</link> a usar durante el proceso
  246. de dispatch y recuperar el objeto actual. Al setear el objeto response, puede
  247. pasarlo en un nombre de clase de response, en cuyo caso el método va a cargar el
  248. archivo clase y lo instanciará. </para>
  249. </listitem>
  250. <listitem>
  251. <para>
  252. <methodname>registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex
  253. = null)</methodname> le permite registrar <link
  254. linkend="zend.controller.plugins">plugin objects</link>. Opcionalmente,
  255. setting <varname>$stackIndex</varname>, puede controlar el orden en que se
  256. ejecutarán los plugins. </para>
  257. </listitem>
  258. <listitem>
  259. <para>
  260. <methodname>unregisterPlugin($plugin)</methodname> le permite desregistrar <link
  261. linkend="zend.controller.plugins">plugin objects</link>.
  262. <varname>$plugin</varname> puede ser tanto un objeto plugin o un string que
  263. denota la clase de plugin a desregistrar. </para>
  264. </listitem>
  265. <listitem>
  266. <para>
  267. <methodname>throwExceptions($flag)</methodname> se utiliza para activar o
  268. desactivar la capacidad de arrojar excepciones durante el proceso de dispatch.
  269. Por defecto, las excepciones son capturadas y colocadas en el <link
  270. linkend="zend.controller.response">objeto response </link>; activando
  271. <methodname>throwExceptions()</methodname> se anulará este comportamiento. </para>
  272. <para> Para más información, lea <xref linkend="zend.controller.exceptions"/>.
  273. </para>
  274. </listitem>
  275. <listitem>
  276. <para>
  277. <methodname>returnResponse($flag)</methodname> se usa para decirle al front
  278. controller cuando regresar la respuesta (<constant>TRUE</constant>) desde
  279. <methodname>dispatch()</methodname>, o si la respuesta debe ser emitida
  280. automáticamente (<constant>FALSE</constant>). Por defecto, la respuesta es
  281. automáticamente emitida (llamando a
  282. <methodname>Zend_Controller_Response_Abstract::sendResponse()</methodname>);
  283. activando <methodname>returnResponse()</methodname>) se anulará este
  284. comportamiento. </para>
  285. <para> Las razones para regresar la respuesta incluyen un deseo de comprobar las
  286. excepciones antes de emitir la respuesta, necesidad de hacer un log de diversos
  287. aspectos de la respuesta (tales como cabeceras), etc. </para>
  288. </listitem>
  289. </itemizedlist>
  290. </sect2>
  291. <sect2 id="zend.controller.front.methods.params">
  292. <title>Parámetros de Front Controller</title>
  293. <para> En la introducción, se indicó que el front controller también actúa como un registro
  294. de los distintos componentes del controlador. Lo hace mediante una familia de métodos
  295. "param". Estos métodos le permiten registrar datos arbitrarios -- objetos y variables --
  296. con el front controller, a ser devueltos en cualquier momento en la cadena de dispatch.
  297. Estos valores se transmiten al router, al dispatcher, y a los action controllers. Los
  298. métodos incluyen: </para>
  299. <itemizedlist>
  300. <listitem>
  301. <para>
  302. <methodname>setParam($name, $value)</methodname> permite establecer un único
  303. parámetro de <varname>$name</varname> con el valor <varname>$value</varname>.
  304. </para>
  305. </listitem>
  306. <listitem>
  307. <para>
  308. <methodname>setParams(array $params)</methodname> permite configurar varios
  309. parámetros a la vez usando un array asociativo. </para>
  310. </listitem>
  311. <listitem>
  312. <para>
  313. <methodname>getParam($name)</methodname> permite recuperar un único parámetro a
  314. la vez, utilizando como identificador a <varname>$name</varname>. </para>
  315. </listitem>
  316. <listitem>
  317. <para>
  318. <methodname>getParams()</methodname> permite recuperar toda la lista de
  319. parámetros a la vez. </para>
  320. </listitem>
  321. <listitem>
  322. <para>
  323. <methodname>clearParams()</methodname> permite borrar un único parámetro
  324. (pasando un string identificador), parámetros con múltiples nombres (pasando un
  325. array de strings identificadores), o el stack de parámetros completo (pasando
  326. nada). </para>
  327. </listitem>
  328. </itemizedlist>
  329. <para> Hay varios parámetros pre-definidos que puede ser seteados para tener usos
  330. específicos en la cadena de dispatch: </para>
  331. <itemizedlist>
  332. <listitem>
  333. <para>
  334. <methodname>useDefaultControllerAlways</methodname> se usa para indicar a <link
  335. linkend="zend.controller.dispatcher">el dispatcher</link> que utilice el
  336. controlador por defecto en el módulo por defecto de cualquier solicitud que no
  337. sea dispatchable (es decir, el módulo, el controlador y/o la acción no existen).
  338. Por defecto, está en off. </para>
  339. <para> Ver <link linkend="zend.controller.exceptions.internal">MVC Exceptions You
  340. May Encounter</link> para información más detallada sobre el uso de este
  341. setting. </para>
  342. </listitem>
  343. <listitem>
  344. <para>
  345. <methodname>disableOutputBuffering</methodname> se usa para indicarle a <link
  346. linkend="zend.controller.dispatcher">el dispatcher</link> que no debe
  347. utilizar output buffering para capturar la salida generada por los controladores
  348. de acción. Por defecto, el dispatcher captura cualquier salida y la añade al
  349. contenido del cuerpo del objeto respuesta. </para>
  350. </listitem>
  351. <listitem>
  352. <para>
  353. <emphasis>noViewRenderer</emphasis> se usa para deshabilitar el <link
  354. linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
  355. Poniendo este parámetro a true, lo deshabilita. </para>
  356. </listitem>
  357. <listitem>
  358. <para>
  359. <emphasis>noErrorHandler</emphasis> se usa para deshabilitar el <link
  360. linkend="zend.controller.plugins.standard.errorhandler">Error Handler
  361. plugin</link>. Poniendo este parámetro a true, lo deshabilita. </para>
  362. </listitem>
  363. </itemizedlist>
  364. </sect2>
  365. <sect2 id="zend.controller.front.subclassing">
  366. <title>Extendiendo el Front Controller</title>
  367. <para> Para extender el Front Controller, como mínimo que necesitará anular el método
  368. <methodname>getInstance()</methodname>: </para>
  369. <programlisting language="php"><![CDATA[
  370. class My_Controller_Front extends Zend_Controller_Front
  371. {
  372. public static function getInstance()
  373. {
  374. if (null === self::$_instance) {
  375. self::$_instance = new self();
  376. }
  377. return self::$_instance;
  378. }
  379. }
  380. ]]></programlisting>
  381. <para> Anulando el método <methodname>getInstance()</methodname> asegura que las
  382. subsiguientes llamadas a <methodname>Zend_Controller_Front::getInstance()</methodname>
  383. devolverá una instancia de su nueva subclase en lugar de una instancia
  384. <classname>Zend_Controller_Front</classname> -- esto es particularmente útil para
  385. algunos de los routers alternativos y view helpers. </para>
  386. <para> Típicamente, no necesitará una subclase del front controller a menos que necesite
  387. añadir nuevas funcionalidades (por ejemplo, un plugin autoloader, o una forma de
  388. especificar los paths de los action helpers). Algunos de los puntos donde puede querer
  389. modificar el comportamiento puede incluir modificar cómo son almacenados los directorios
  390. de controladores , o qué router predeterminado o dispatcher se utiliza. </para>
  391. </sect2>
  392. </sect1>