Zend_Controller-FrontController.xml 26 KB

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