1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 17397 -->
4 <sect1 id="zend.application.theory-of-operation">
5 <title>Működési elv</title>
8 Egy <acronym>MVC</acronym> alkalmazás beállítása és felkészítése az indulásra egyre növekvő
9 mennyiségű kódot igényelt, ahogy egyre több és több lehetőség állt rendelkezésre: beállítani
10 az adatbázist, a nézetet és a nézet segédeket, az elrendezéseket, bejegyezni a
11 bővítményeket, művelet segédeket és a többi.
15 Ezen felül gyakoran igény lehet ugyanazon kód használata a tesztek, ütemezett feladatok vagy
16 egy webszolgáltatás rendszertöltéséhez. Miközben lehetséges egyszerűen beilleszteni a
17 rendszertöltő állományt, gyakori, hogy bizonyos beállítások környezetre jellemzők – nem
18 szükséges az <acronym>MVC</acronym> egy ütemezett feladathoz, vagy az adatbázis réteg egy
23 A <classname>Zend_Application</classname> célja ennek leegyszerűsítése és az újrahasznosítás
24 elősegítése a rendszertöltés <acronym>OOP</acronym> mintákba zárásával.
28 A <classname>Zend_Application</classname> három részre bontható:
34 <classname>Zend_Application</classname>: betölti a <acronym>PHP</acronym>
35 környezetet, beleértve az include_path-t és az automatikus betöltést, illetve
36 példányosítja a kért rendszertöltő osztályt.
41 <classname>Zend_Application_Bootstrap</classname>: felületeket nyújt a rendszertöltő
42 osztályoknak. A <classname>Zend_Application_Bootstrap_Bootstrap</classname> a
43 legtöbb rendszertöltővel szemben támasztható igényt kielégítő funkcionalitást nyújt,
44 beleértve a függőség-ellenőrző algoritmusokat és a rendszertöltő erőforrások igény
50 A <classname>Zend_Application_Resource</classname> szabványos, egy rendszertöltő
51 példány által igény szerint betölthető erőforrásokhoz nyújt felületet, csakúgy, mint
52 több kész megvalósítást.
58 A fejlesztők a <classname>Zend_Application_Bootstrap_Bootstrap</classname> kiterjesztésével
59 vagy (legkevesebb) a <classname>Zend_Application_Bootstrap_Bootstrapper</classname>
60 megvalósításával hozhatnak létre rendszertöltőt alkalmazásukhoz. A belépési pont
61 (<filename>public/index.php</filename>, pl.) betölti és példányosítja a
62 <classname>Zend_Application</classname>-t
68 a pillanatnyi környezet és
73 a rendszertöltés beállításainak
82 Utóbbiak magukban foglalják a rendszertöltő osztályt tartalmazó állomány elérési útját,
83 illetve igény szerint:
89 további include_path összetevőket;
94 további automatikus betöltéshez bejegyzendő névtereket;
99 beállítandó <filename>php.ini</filename> értékeket;
104 a rendszertöltő osztály nevét (ha nem „Bootstrap”)
109 erőforrás előtagat a az elérési utakhoz;
114 használandó erőforrásokat (az osztály neve vagy rövid név szerint);
119 további elérési utakat konfigurációs állományok betöltéséhez, illetve
124 további konfigurációs beállításokat.
130 A beállítások érkezhetnek egy tömbben, egy <classname>Zend_Config</classname> objektumban
131 vagy egy konfigurációs állomány elérési útja képében.
134 <sect2 id="zend.application.theory-of-operation.bootstrap">
135 <title>Rendszertöltés</title>
138 A <classname>Zend_Application</classname> felelősségi körébe tartozik az alkalmazás
139 rendszertöltőjének végrehajtása is. Egy rendszertöltőnek legkevesebb meg kell
140 valósítania <classname>Zend_Application_Bootstrap_Bootstrapper</classname>-t, mely
141 a következő <acronym>API</acronym>-t határozza meg:
144 <programlisting language="php"><![CDATA[
145 interface Zend_Application_Bootstrap_Bootstrapper
147 public function __construct($application);
148 public function setOptions(array $options);
149 public function getApplication();
150 public function getEnvironment();
151 public function getClassResources();
152 public function getClassResourceNames();
153 public function bootstrap($resource = null);
154 public function run();
159 Ez az <acronym>API</acronym> lehetővé teszi a rendszertöltőnek a környezet és
160 beállítások fogadását az alkalmazás objektumtól, hogy jelentsen az erőforrásokról,
161 melyek indításáért felelős, majd betöltse és futtassa az alkalmazást.
165 A felület megvalósítható önállóan, lehetőség van a
166 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> kiterjesztésére
167 vagy a <classname>Zend_Application_Bootstrap_Bootstrap</classname> használatára.
171 Ezek mellett egy sor más dolog is van, mellyel érdemes megismerkedni.
174 <sect3 id="zend.application.theory-of-operation.bootstrap.resource-methods">
175 <title>Erőforrás tagfüggvények</title>
178 A <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> megvalósítás
179 egy egyszerű egyezményt nyújt erőforrás tagfüggvények meghatározására. Minden védett
180 tagfüggvény, mely az <emphasis>_init</emphasis> előtaggal kezdődik, erőforrás
181 tagfüggvénynek számít.
185 Egy adott erőforrás tagfüggvény betöltéséhez a <methodname>bootstrap()</methodname>
186 metódus használatos az erőforrás nevének megadásával. A név a tagfüggvény neve az
187 <emphasis>_init</emphasis> előtag elhagyásával.
191 Több tagfüggvény betöltéséhez egy tömböt kell átadni, az összeséhez pedig semmit.
195 Vegyük a következő rendszertöltő osztályt:
198 <programlisting language="php"><![CDATA[
199 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
201 protected function _initFoo()
206 protected function _initBar()
211 protected function _initBaz()
219 Az <methodname>_initFoo()</methodname> tagfüggvény betöltéséhez a következő a
223 <programlisting language="php"><![CDATA[
224 $bootstrap->bootstrap('foo');
228 Az <methodname>_initFoo()</methodname> és az <methodname>_initBar()</methodname>
229 betöltéséhez a következő:
232 <programlisting language="php"><![CDATA[
233 $bootstrap->bootstrap(array('foo', 'bar'));
237 Az öszes betöltéséhez a <methodname>bootstrap()</methodname> argumentumok nélkül
241 <programlisting language="php"><![CDATA[
242 $bootstrap->bootstrap();
246 <sect3 id="zend.application.theory-of-operation.bootstrap.resource-plugins">
247 <title>Bootstraps that use resource plugins</title>
250 To make your bootstraps more re-usable, we have provided the
251 ability to push your resources into resource plugin classes.
252 This allows you to mix and match resources simply via
253 configuration. We will cover <link
254 linkend="zend.application.theory-of-operation.resources">how
255 to create resources</link> later; in
256 this section we will show you how to utilize them only.
260 If your bootstrap should be capable of using resource plugins,
261 you will need to implement an additional interface,
262 <classname>Zend_Application_Bootstrap_ResourceBootstrapper</classname>.
263 This interface defines an <acronym>API</acronym> for locating, registering, and
264 loading resource plugins:
267 <programlisting language="php"><![CDATA[
268 interface Zend_Application_Bootstrap_ResourceBootstrapper
270 public function registerPluginResource($resource, $options = null);
271 public function unregisterPluginResource($resource);
272 public function hasPluginResource($resource);
273 public function getPluginResource($resource);
274 public function getPluginResources();
275 public function getPluginResourceNames();
276 public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader);
277 public function getPluginLoader();
282 Resource plugins basically provide the ability to create
283 resource intializers that can be re-used between applications.
284 This allows you to keep your actual bootstrap relatively clean,
285 and to introduce new resources without needing to touch your
290 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> (and
291 <classname>Zend_Application_Bootstrap_Bootstrap</classname> by extension)
292 implement this interface as well, allowing you to utilize
297 To utilize resource plugins, you must specify them in the
298 options passed to the application object and/or bootstrap. These
299 options may come from a configuration file, or be passed in
300 manually. Options will be of key to options pairs, with the key
301 representing the resource name. The resource name will be the
302 segment following the class prefix. For example, the resources
303 shipped with Zend Framework have the class prefix
304 "<classname>Zend_Application_Resource_</classname>"; anything following this would
305 be the name of the resource. As an example,
308 <programlisting language="php"><![CDATA[
309 $application = new Zend_Application(APPLICATION_ENV, array(
310 'resources' => array(
311 'FrontController' => array(
312 'controllerDirectory' => APPLICATION_PATH . '/controllers',
319 This indicates that the "FrontController" resource should be
320 used, with the options specified.
324 If you begin writing your own resource plugins, or utilize
325 third-party resource plugins, you will need to tell your
326 bootstrap where to look for them. Internally, the bootstrap
327 utilizes <classname>Zend_Loader_PluginLoader</classname>, so you will only
328 need to indicate the common class prefix an path pairs.
332 As an example, let's assume you have custom resource plugins in
333 <filename>APPLICATION_PATH/resources/</filename> and that they share the
334 common class prefix of <classname>My_Resource</classname>. You would then
335 pass that information to the application object as follows:
338 <programlisting language="php"><![CDATA[
339 $application = new Zend_Application(APPLICATION_ENV, array(
340 'pluginPaths' => array(
341 'My_Resource' => APPLICATION_PATH . '/resources/',
343 'resources' => array(
344 'FrontController' => array(
345 'controllerDirectory' => APPLICATION_PATH . '/controllers',
352 You would now be able to use resources from that directory.
356 Just like resource methods, you use the <methodname>bootstrap()</methodname>
357 method to execute resource plugins. Just like with resource
358 methods, you can specify either a single resource plugin,
359 multiple plugins (via an array), or all plugins. Additionally,
360 you can mix and match to execute resource methods as well.
363 <programlisting language="php"><![CDATA[
365 $bootstrap->bootstrap('FrontController');
368 $bootstrap->bootstrap(array('FrontController', 'Foo'));
370 // Execute all resource methods and plugins:
371 $bootstrap->bootstrap();
375 <sect3 id="zend.application.theory-of-operation.bootstrap.registry">
376 <title>Resource Registry</title>
379 Many, if not all, of your resource methods or plugins will
380 initialize objects, and in many cases, these objects will be
381 needed elsewhere in your application. How can you access them?
385 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
386 provides a local registry for these objects. To store your
387 objects in them, you simply return them from your resources.
391 For maximum flexibility, this registry is referred to as a
392 "container" internally; its only requirements are that it is an
393 object. Resources are then registered as properties named after
394 the resource name. By default, an instance of
395 <classname>Zend_Registry</classname> is used, but you may also specify any
396 other object you wish. The methods <methodname>setContainer()</methodname>
397 and <methodname>getContainer()</methodname> may be used to manipulate the
398 container itself. <methodname>getResource($resource)</methodname> can be
399 used to fetch a given resource from the container, and
400 <methodname>hasResource($resource)</methodname> to check if the resource has
401 actually been registered.
405 As an example, consider a basic view resource:
408 <programlisting language="php"><![CDATA[
409 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
411 protected function _initView()
413 $view = new Zend_View();
414 // more initialization...
422 You can then check for it and/or fetch it as follows:
425 <programlisting language="php"><![CDATA[
426 // Using the has/getResource() pair:
427 if ($bootstrap->hasResource('view')) {
428 $view = $bootstrap->getResource('view');
431 // Via the container:
432 $container = $bootstrap->getContainer();
433 if (isset($container->view)) {
434 $view = $container->view;
439 Please note that the registry and also the container is not global. This
440 means that you need access to the bootstrap in order to fetch
441 resources. <classname>Zend_Application_Bootstrap_Bootstrap</classname>
442 provides some convenience for this: during its
443 <methodname>run()</methodname> execution, it registers itself as the front
444 controller parameter "bootstrap", which allows you to fetch it
445 from the router, dispatcher, plugins, and action controllers.
449 As an example, if you wanted access to the view resource from
450 above within your action controller, you could do the following:
453 <programlisting language="php"><![CDATA[
454 class FooController extends Zend_Controller_Action
456 public function init()
458 $bootstrap = $this->getInvokeArg('bootstrap');
459 $view = $bootstrap->getResource('view');
466 <sect3 id="zend.application.theory-of-operation.bootstrap.dependency-tracking">
467 <title>Dependency Tracking</title>
470 In addition to executing resource methods and plugins, it's
471 necessary to ensure that these are executed once and once
472 only; these are meant to bootstrap an application, and
473 executing multiple times can lead to resource overhead.
477 At the same time, some resources may depend on other
478 resources being executed. To solve these two issues,
479 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
480 provides a simple, effective mechanism for dependency
485 As noted previously, all resources -- whether methods or plugins
486 -- are bootstrapped by calling <methodname>bootstrap($resource)</methodname>,
487 where <varname>$resource</varname> is the name of a resource, an array
488 of resources, or, left empty, indicates all resources should be
493 If a resource depends on another resource, it should call
494 <methodname>bootstrap()</methodname> within its code to ensure that resource
495 has been executed. Subsequent calls to it will then be ignored.
499 In a resource method, such a call would look like this:
502 <programlisting language="php"><![CDATA[
503 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
505 protected function _initRequest()
507 // Ensure the front controller is initialized
508 $this->bootstrap('FrontController');
510 // Retrieve the front controller from the bootstrap registry
511 $front = $this->getResource('FrontController');
513 $request = new Zend_Controller_Request_Http();
514 $request->setBaseUrl('/foo');
515 $front->setRequest($request);
517 // Ensure the request is stored in the bootstrap registry
525 <sect2 id="zend.application.theory-of-operation.resources">
526 <title>Resource Plugins</title>
530 linkend="zend.application.theory-of-operation.bootstrap.resource-plugins">As noted
531 previously</link>, a good way to create re-usable bootstrap resources and to
532 offload much of your coding to discrete classes is to utilize resource
533 plugins. While Zend Framework ships with a number of standard
534 resource plugins, the intention is that developers should write
535 their own to encapsulate their own initialization needs.
539 Resources need only implement
540 <classname>Zend_Application_Resource_Resource</classname>, or, more simply
542 <classname>Zend_Application_Resource_ResourceAbstract</classname>. The basic
543 interface is simply this:
546 <programlisting language="php"><![CDATA[
547 interface Zend_Application_Resource_Resource
549 public function __construct($options = null);
550 public function setBootstrap(
551 Zend_Application_Bootstrap_Bootstrapper $bootstrap
553 public function getBootstrap();
554 public function setOptions(array $options);
555 public function getOptions();
556 public function init();
561 The interface defines simply that a resource should accept options
562 to the constructor, have mechanisms for setting and retrieving
563 options, have mechanisms for setting and retrieving the bootstrap
564 object, and an initialization method.
568 As an example, let's assume you have a common view intialization you
569 use in your applications. You have a common doctype, <acronym>CSS</acronym> and
570 JavaScript, and you want to be able to pass in a base document title
571 via configuration. Such a resource might look like this:
574 <programlisting language="php"><![CDATA[
575 class My_Resource_View extends Zend_Application_Resource_ResourceAbstract
579 public function init()
581 // Return view so bootstrap will store it in the registry
582 return $this->getView();
585 public function getView()
587 if (null === $this->_view) {
588 $options = $this->getOptions();
590 if (array_key_exists('title', $options)) {
591 $title = $options['title'];
592 unset($options['title']);
595 $view = new Zend_View($options);
596 $view->doctype('XHTML1_STRICT');
597 $view->headTitle($title);
598 $view->headLink()->appendStylesheet('/css/site.css');
599 $view->headScript()->appendfile('/js/analytics.js');
602 Zend_Controller_Action_HelperBroker::getStaticHelper(
605 $viewRenderer->setView($view);
607 $this->_view = $view;
615 As long as you register the prefix path for this resource plugin,
616 you can then use it in your application. Even better, because it
617 uses the plugin loader, you are effectively overriding the shipped
618 "View" resource plugin, ensuring that your own is used instead.