Zend_Controller-FrontController.xml 26 KB

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