Zend_Application-TheoryOfOperation.xml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15103 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.application.theory-of-operation">
  5. <title>Teoría de Operación</title>
  6. <para>
  7. Obtener una aplicación MVC configurada y lista para funcionar ha
  8. requerido una cantidad de código creciente al disponer de una mayor
  9. cantidad de características: estableciendo la base de datos,
  10. configurar su vista y los ayudantes de vistas, configurar su diseños,
  11. colocando plugins, registrando ayudantes de acción, y mucho más.
  12. </para>
  13. <para>
  14. Además, a menudo deseará reutilizar el mismo código para arrancar sus
  15. pruebas, un cronjob, o un servicio script.
  16. Si bien es posible incluir simplemente su script bootstrap,
  17. a menudo hay initializaciones que son específicas del medio ambiente,
  18. puede que usted no necesite el MVC para un cronjob, o simplemente
  19. la capa de DB para un servicio script.
  20. </para>
  21. <para>
  22. <classname>Zend_Application</classname> pretende hacer esto más fácil
  23. y promover la reutilización mediante el encapsulamiento del
  24. bootstraping en paradigmas de OOP.
  25. </para>
  26. <para>
  27. Zend_Application está dividida en tres áreas:
  28. </para>
  29. <itemizedlist>
  30. <listitem>
  31. <para>
  32. <classname>Zend_Application</classname>: carga el medio
  33. ambiente de PHP, incluyendo include_paths y autocarga,
  34. e instancia la clase requerida de bootstrap.
  35. </para>
  36. </listitem>
  37. <listitem>
  38. <para>
  39. <classname>Zend_Application_Bootstrap</classname>: suministra
  40. interfaces para las clases bootstrap.
  41. <classname>Zend_Application_Bootstrap_Bootstrap</classname>
  42. ofrece funcionalidad común para la mayoría de las necesidades
  43. de bootstrap, incluyendo algoritmos de comprobación de
  44. dependencias y la capacidad de cargar recursos de bootstrap
  45. por demanda.
  46. </para>
  47. </listitem>
  48. <listitem>
  49. <para>
  50. <classname>Zend_Application_Resource</classname> provee una
  51. interfaz para recursos standard de bootstrap que pueden ser
  52. cargados por demanda mediante una instancia bootstrap,
  53. así como implementaciones de varios recursos por defecto.
  54. </para>
  55. </listitem>
  56. </itemizedlist>
  57. <para>
  58. Los desarrolladores crean una clase de arranque(bootstrap) para sus
  59. aplicaciones, extendiendo
  60. <classname>Zend_Application_Bootstrap_Bootstrap</classname> o
  61. implementando (mínimamente)
  62. <classname>Zend_Application_Bootstrap_Bootstrapper</classname>. El punto de entrada
  63. (e.g., public/index.php) cargará <classname>Zend_Application</classname>,
  64. y la instanciará pasando:
  65. </para>
  66. <itemizedlist>
  67. <listitem>
  68. <para>
  69. El medio ambiente actual
  70. </para>
  71. </listitem>
  72. <listitem>
  73. <para>
  74. Opciones para bootstrapping
  75. </para>
  76. </listitem>
  77. </itemizedlist>
  78. <para>
  79. Las opciones de bootstrap incluyen el path hacia el archivo que
  80. contiene la clase bootstrap y opcionalmente:
  81. </para>
  82. <itemizedlist>
  83. <listitem>
  84. <para>
  85. Cualquier include_paths extras a establecer
  86. </para>
  87. </listitem>
  88. <listitem>
  89. <para>
  90. Cualquier otro namespace de autocarga adicional a registrar
  91. </para>
  92. </listitem>
  93. <listitem>
  94. <para>
  95. Cualquier setting de php.ini a inicializar
  96. </para>
  97. </listitem>
  98. <listitem>
  99. <para>
  100. El nombre de clase para la clase bootstrap (si no es "Bootstrap")
  101. </para>
  102. </listitem>
  103. <listitem>
  104. <para>
  105. Pares de recursos prefijo/path a usar
  106. </para>
  107. </listitem>
  108. <listitem>
  109. <para>
  110. Cualquier recurso a usar (por nombre de clase o nombre corto)
  111. </para>
  112. </listitem>
  113. <listitem>
  114. <para>
  115. Path adicional al archivo de configuración a cargar
  116. </para>
  117. </listitem>
  118. <listitem>
  119. <para>
  120. Opciones adicionales de configuración
  121. </para>
  122. </listitem>
  123. </itemizedlist>
  124. <para>
  125. Las opciones puden ser una array, un objeto
  126. <classname>Zend_Config</classname>, o el path a un archivo de
  127. configuración.
  128. </para>
  129. <sect2 id="zend.application.theory-of-operation.bootstrap">
  130. <title>Bootstrapping</title>
  131. <para>
  132. La segunda área de responsabilidad de
  133. <classname>Zend_Application</classname> es ejecutar la aplicación
  134. bootstrap. Los bootstraps necesitan mínimamente implementar
  135. <classname>Zend_Application_Bootstrap_Bootstrapper</classname>,
  136. la que define la siguiente API:
  137. </para>
  138. <programlisting role="php"><![CDATA[
  139. interface Zend_Application_Bootstrap_Bootstrapper
  140. {
  141. public function __construct($application);
  142. public function setOptions(array $options);
  143. public function getApplication();
  144. public function getEnvironment();
  145. public function getClassResources();
  146. public function getClassResourceNames();
  147. public function bootstrap($resource = null);
  148. public function run();
  149. }
  150. ]]></programlisting>
  151. <para>
  152. Esta API permite aceptar al bootstrap el medio ambiente y a la
  153. configuración desde el objeto aplicación, informa la
  154. responsabilidad de los recursos para los recursos bootstraping,
  155. luego hace el bootstrap y ejecuta la aplicación.
  156. </para>
  157. <para>
  158. Puede implementar esta interfaz usted mismo, extendiendo
  159. <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>,
  160. o usar
  161. <classname>Zend_Application_Bootstrap_Bootstrap</classname>.
  162. </para>
  163. <para>
  164. Además de esta funcionalidad, hay muchas otras áreas de
  165. incumbencia con las cuales debe familiarizarse.
  166. </para>
  167. <sect3 id="zend.application.theory-of-operation.bootstrap.resource-methods">
  168. <title>Métodos Recursos</title>
  169. <para>
  170. La implementación de
  171. <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
  172. proporciona una simple convención para definir métodos de
  173. recursos de clase. Cualquier método protegido cuyo nombre
  174. comience con un prefijo <code>_init</code> será considerado
  175. un método de recurso.
  176. </para>
  177. <para>
  178. Para arrancar un único método de recurso, utilizar el método
  179. <code>bootstrap()</code>, y pasarle el nombre del recurso.
  180. El nombre será el nombre de método menos el prefijo
  181. <code>_init</code>.
  182. </para>
  183. <para>
  184. Para arrancar varios métodos de recursos, pasar un array de
  185. nombres. Para bootstrap de todos los métodos de recursos,
  186. no pasar nada.
  187. </para>
  188. <para>
  189. Tome las siguientes clases bootstrap:
  190. </para>
  191. <programlisting role="php"><![CDATA[
  192. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  193. {
  194. protected function _initFoo()
  195. {
  196. // ...
  197. }
  198. protected function _initBar()
  199. {
  200. // ...
  201. }
  202. protected function _initBaz()
  203. {
  204. // ...
  205. }
  206. }
  207. ]]></programlisting>
  208. <para>
  209. Para arrancar solo el método <code>_initFoo()</code>, haga lo
  210. siguiente:
  211. </para>
  212. <programlisting role="php"><![CDATA[
  213. $bootstrap->bootstrap('foo');
  214. ]]></programlisting>
  215. <para>
  216. Para arrancar los métodos <code>_initFoo()</code> y
  217. <code>_initBar()</code> , haga lo siguiente:
  218. </para>
  219. <programlisting role="php"><![CDATA[
  220. $bootstrap->bootstrap(array('foo', 'bar));
  221. ]]></programlisting>
  222. <para>
  223. Para arrancar todos los métodos de recursos, llame a
  224. <code>code>bootstrap()</code> sin argumentos:
  225. </para>
  226. <programlisting role="php"><![CDATA[
  227. $bootstrap->bootstrap();
  228. ]]></programlisting>
  229. </sect3>
  230. <sect3 id="zend.application.theory-of-operation.bootstrap.resource-plugins">
  231. <title>Bootstraps que usan plugins de recursos</title>
  232. <para>
  233. Para hacer más re-utilizables sus bootstraps, hemos
  234. proporcionado la capacidad de impulsar sus recursos dentro de
  235. las clases de recursos de plugin. Esto le permite combinar
  236. recursos simplemente via configuración. Cubriremos el tema
  237. <link
  238. linkend="zend.application.theory-of-operation.resources">cómo
  239. crear recursos</link> más adelante; en esta sección le
  240. mostraremos sólo cómo utilizarlos.
  241. </para>
  242. <para>
  243. Si su bootstrap debe ser capaz de utilizar recursos de plugins,
  244. necesitará implementar una interfaz adicional,
  245. <classname>Zend_Application_Bootstrap_ResourceBootstrapper</classname>.
  246. Esta interfaz define una API para localizar, registrar,
  247. y cargar recursos de plugins:
  248. </para>
  249. <programlisting role="php"><![CDATA[
  250. interface Zend_Application_Bootstrap_ResourceBootstrapper
  251. {
  252. public function registerPluginResource($resource, $options = null);
  253. public function unregisterPluginResource($resource);
  254. public function hasPluginResource($resource);
  255. public function getPluginResource($resource);
  256. public function getPluginResources();
  257. public function getPluginResourceNames();
  258. public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader);
  259. public function getPluginLoader();
  260. }
  261. ]]></programlisting>
  262. <para>
  263. Básicamente los recursos de plugins ofrecen la posibilidad de
  264. crear recursos incializadores que puede ser re-utilizados entre
  265. aplicaciones. Esto le permite mantener su actual bootstrap
  266. relativamente limpio, e introducir nuevos recursos
  267. sin necesidad de tocar su propio arranque (bootstrap).
  268. </para>
  269. <para>
  270. <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> (y
  271. <classname>Zend_Application_Bootstrap_Bootstrap</classname> por extensión)
  272. implementan esta interfaz, que le permite utilizar recursos de
  273. plugins.
  274. </para>
  275. <para>
  276. Para utilizar recursos de plugins, debe especificarlos en las
  277. opciones que pasó al objeto aplicación y/o bootstrap.
  278. Estas opciones pueden provenir de un archivo de configuración,
  279. o ser pasadas manualmente.
  280. Las opciones deberán ser pares de clave/opción, representando
  281. con la clave el nombre del recurso. El nombre de recurso será
  282. el segmento siguiente al prefijo de clase.
  283. Por ejemplo, los recursos que vienen con Zend Framework
  284. tienen el prefijo de clase "Zend_Application_Resource_";
  285. cualquier cosa que le siga después debe ser el nombre del recurso.
  286. Como por ejemplo,
  287. </para>
  288. <programlisting role="php"><![CDATA[
  289. $application = new Zend_Application(APPLICATION_ENV, array(
  290. 'resources' => array(
  291. 'FrontController' => array(
  292. 'controllerDirectory' => APPLICATION_PATH . '/controllers',
  293. ),
  294. ),
  295. ));
  296. ]]></programlisting>
  297. <para>
  298. Esto indica que el recurso "Front Controller", debería ser
  299. utilizado, con las opciones especificadas.
  300. </para>
  301. <para>
  302. Si usted comienza a escribir su propio recurso de plugin,
  303. o utilizar recursos de plugin de terceras partes,
  304. necesitará decirle a su bootstrap donde encontrarlos.
  305. Internamente, el bootstrap utiliza
  306. <classname>Zend_Loader_PluginLoader</classname>, de manera tal
  307. que sólo necesitará indicar el prefijo de la clase común como
  308. pares de path.
  309. </para>
  310. <para>
  311. Supongamos por ejemplo, que usted tiene recursos de plugins
  312. personalizados en <code>APPLICATION_PATH/resources/</code> y que
  313. ellos comparten el prefijo de clase común <code>My_Resource</code>.
  314. Entonces, debería pasar esa información al objeto aplicación
  315. de la siguiente manera:
  316. </para>
  317. <programlisting role="php"><![CDATA[
  318. $application = new Zend_Application(APPLICATION_ENV, array(
  319. 'pluginPaths' => array(
  320. 'My_Resource' => APPLICATION_PATH . '/resources/',
  321. ),
  322. 'resources' => array(
  323. 'FrontController' => array(
  324. 'controllerDirectory' => APPLICATION_PATH . '/controllers',
  325. ),
  326. ),
  327. ));
  328. ]]></programlisting>
  329. <para>
  330. Ahora usted está habilitado para utilizar los recursos de
  331. ese directorio.
  332. </para>
  333. <para>
  334. Tal como los métodos de recursos, utilice el método bootstrap()
  335. para ejecutar recursos de plugins. También tal como con los
  336. métodos de recursos, puede especificar bien un único recurso de
  337. plugin, múltiples plugins (vía un array), o todos los plugins.
  338. Además, los puede combinar para ejecutar métodos de recursos.
  339. </para>
  340. <programlisting role="php"><![CDATA[
  341. // Ejecute uno:
  342. $bootstrap->bootstrap('FrontController');
  343. // Ejecute varios:
  344. $bootstrap->bootstrap(array('FrontController', 'Foo'));
  345. // Ejecute todos los métodos de recursos y plugins:
  346. $bootstrap->bootstrap();
  347. ]]></programlisting>
  348. </sect3>
  349. <sect3 id="zend.application.theory-of-operation.bootstrap.registry">
  350. <title>Registro de Recursos</title>
  351. <para>
  352. Muchos, si no todos, sus métodos de recursos o plugins
  353. inicializarán objetos y, en muchos casos, estos objetos serán
  354. necesarios en otros lugares de su aplicación.
  355. ¿Cómo se puede acceder a ellos?
  356. </para>
  357. <para>
  358. <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
  359. ofrece un registro local para estos objetos. Para almacenar sus
  360. objetos en ellos, simplemente debe devolverlos desde sus recursos.
  361. </para>
  362. <para>
  363. Para máxima flexibilidad, este registro es mencionado
  364. internamente como un "contenedor"; el único requisito es que
  365. sea un objeto. Los recursos son luego registrados como
  366. propiedades nombrados después del nombre del recurso.
  367. Por defecto, una instancia de
  368. <classname>Zend_Registry</classname> es utilizada, pero
  369. también puede especificar cualquier otro objeto que desee.
  370. Los métodos <code>setContainer()</code> y <code>getContainer()</code>
  371. pueden ser utilizados para manipular el contenedor en si mismo.
  372. <code>getResource($resource)</code> puede ser utilizado para
  373. recuperar un recurso determinado del contenedor, y
  374. <code>hasResource($resource)</code> para verificar si el
  375. recurso ha sido efectivamente registrado.
  376. </para>
  377. <para>
  378. Como ejemplo, considere una visión básica del recurso:
  379. </para>
  380. <programlisting role="php"><![CDATA[
  381. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  382. {
  383. protected function _initView()
  384. {
  385. $view = new Zend_View();
  386. // más inicialización...
  387. return $view;
  388. }
  389. }
  390. ]]></programlisting>
  391. <para>
  392. A continuación, puede comprobarlos y/o traerlos así:
  393. </para>
  394. <programlisting role="php"><![CDATA[
  395. // Usando el par has/getResource():
  396. if ($bootstrap->hasResource('view')) {
  397. $view = $bootstrap->getResource('view');
  398. }
  399. // Via el contenedor:
  400. $container = $bootstrap->getContainer();
  401. if (isset($container->view)) {
  402. $view = $container->view;
  403. }
  404. ]]></programlisting>
  405. <para>
  406. Tenga en cuenta que el registro/contenedor no es global.
  407. Esto significa que usted necesita acceso al bootstrap a fin de
  408. recuperar recursos. <classname>Zend_Application_Bootstrap_Bootstrap</classname>
  409. proporciona cierta comodidad para ello: durante las ejecución de
  410. <code>run()</code> se registra a sí mismo como el "Front
  411. Controller" en el parámetro del "bootstrap", que permite
  412. buscarlo desde el router, despachador, plugins, y los
  413. contoladores de acción.
  414. </para>
  415. <para>
  416. Como ejemplo, si quiere tener acceso a los recursos de la
  417. vista desde dentro de su controlador de acción, podría
  418. hacer lo siguiente:
  419. </para>
  420. <programlisting role="php"><![CDATA[
  421. class FooController extends Zend_Controller_Action
  422. {
  423. public function init()
  424. {
  425. $bootstrap = $this->getInvokeArg('bootstrap');
  426. $view = $bootstrap->getResource('view');
  427. // ...
  428. }
  429. }
  430. ]]></programlisting>
  431. </sect3>
  432. <sect3 id="zend.application.theory-of-operation.bootstrap.dependency-tracking">
  433. <title>Localización de las Dependencias</title>
  434. <para>
  435. Además de ejecutar los métodos de recursos métodos y plugins,
  436. es necesario garantizar que estos son ejecutados una vez y solo
  437. una vez; esto es lo que se pretende con el bootstrap de una
  438. aplicación, y ejecutarlo múltiples veces puede conducir a
  439. una sobrecarga de recursos.
  440. </para>
  441. <para>
  442. Al mismo tiempo, algunos recursos puede depender de otros
  443. que están en ejecución. Para resolver estas dos cuestiones,
  444. <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
  445. proporciona un mecanismo simple pero eficaz para la localización
  446. de dependencias.
  447. </para>
  448. <para>
  449. Como se señaló anteriormente, todos los recursos --
  450. ya sean métodos o plugins -- son arrancados llamando a
  451. <code>bootstrap($resource)</code>, dende <code>$resource</code>
  452. es el nombre de un recurso, un array de recursos,
  453. o si se dejó vacío, indica que deberían ejecutarse todos los recursos.
  454. </para>
  455. <para>
  456. Si un recurso depende de otro recurso, debe llamar a
  457. <code>bootstrap()</code> dentro de su código para garantizar
  458. que ese recurso ha sido ejecutado.
  459. Las llamadas subsiguientes a él, serán ignoradas.
  460. </para>
  461. <para>
  462. En un método de recursos, esa llamada sería parecida a lo siguiente:
  463. </para>
  464. <programlisting role="php"><![CDATA[
  465. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  466. {
  467. protected function _initRequest()
  468. {
  469. // Asegurar que el front controller es inicializado
  470. $this->bootstrap('FrontController');
  471. // Recuperar el front controller desde el registro de bootstrap
  472. $front = $this->getResource('FrontController');
  473. $request = new Zend_Controller_Request_Http();
  474. $request->setBaseUrl('/foo');
  475. $front->setRequest($request);
  476. // Garantizar que la solicitud es almacenada en el registro de bootstrap
  477. return $request;
  478. }
  479. }
  480. ]]></programlisting>
  481. </sect3>
  482. </sect2>
  483. <sect2 id="zend.application.theory-of-operation.resources">
  484. <title>Plugins de Recursos</title>
  485. <para>
  486. <link linkend="zend.application.theory-of-operation.bootstrap.resource-plugins">Como se señaló anteriormente</link>,
  487. una buena forma de crear recursos de bootstrap re-utilizables y a
  488. traspasar mucha de su codificación a clases discretas es utilizar
  489. plugins de recursos. Si bien Zend Framework se entrega con una
  490. serie de plugins de recursos, la intención es que los
  491. desarrolladores deberían escribir los suyos para encapsular
  492. sus propias necesidades de inicialización.
  493. </para>
  494. <para>
  495. Los recursos solo necesitan implemetarse
  496. <classname>Zend_Application_Resource_Resource</classname>, o
  497. más simple aún, extenderse
  498. <classname>Zend_Application_Resource_ResourceAbstract</classname>.
  499. La interfaz básica es simplemente esto:
  500. </para>
  501. <programlisting role="php"><![CDATA[
  502. interface Zend_Application_Resource_Resource
  503. {
  504. public function __construct($options = null);
  505. public function setBootstrap(
  506. Zend_Application_Bootstrap_Bootstrapper $bootstrap
  507. );
  508. public function getBootstrap();
  509. public function setOptions(array $options);
  510. public function getOptions();
  511. public function init();
  512. }
  513. ]]></programlisting>
  514. <para>
  515. La interfaz define simplemente que un recurso debe aceptar opciones
  516. para el constructor, tiene mecanismos de establecer y recuperar
  517. opciones, mecanismos de establecer y recuperar el objeto bootstrap,
  518. y un método de inicialización.
  519. </para>
  520. <para>
  521. Como ejemplo, supongamos que tiene una vista común de inicialización
  522. que utiliza en sus aplicaciones. Usted tiene un doctype común, CSS
  523. y JavaScript, y quiere se capaz de pasar desde un documento base el
  524. título via configuración. Un recurso tal podría ser como este:
  525. </para>
  526. <programlisting role="php"><![CDATA[
  527. class My_Resource_View extends Zend_Application_Resource_ResourceAbstract
  528. {
  529. protected $_view;
  530. public function init()
  531. {
  532. // Regresa la vista de manera que bootstrap la almacenará en el registro
  533. return $this->getView();
  534. }
  535. public function getView()
  536. {
  537. if (null === $this->_view) {
  538. $options = $this->getOptions();
  539. $title = '';
  540. if (array_key_exists('title', $options)) {
  541. $title = $options['title'];
  542. unset($options['title]);
  543. }
  544. $view = new Zend_View($options);
  545. $view->doctype('XHTML1_STRICT');
  546. $view->headTitle($title);
  547. $view->headLink()->appendStylesheet('/css/site.css');
  548. $view->headScript()->appendfile('/js/analytics.js');
  549. $viewRenderer =
  550. Zend_Controller_Action_HelperBroker::getStaticHelper(
  551. 'ViewRenderer',
  552. );
  553. $viewRenderer->setView($view);
  554. $this->_view = $view;
  555. }
  556. return $this->_view;
  557. }
  558. }
  559. ]]></programlisting>
  560. <para>
  561. Minetrtas usted haya registrado el path del prefijo para este
  562. recurso de plugin, puede usarlo en su aplicación. Mejor aún,
  563. ya que usa el cargador de plugin, usted está pasando por encima del
  564. recurso de plugin de la "View" que viene con Zend Framework,
  565. se está asegurando así que usa el suyo en lugar del original.
  566. </para>
  567. </sect2>
  568. </sect1>