| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 17397 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.application.theory-of-operation">
- <title>Működési elv</title>
- <para>
- Egy <acronym>MVC</acronym> alkalmazás beállítása és felkészítése az indulásra egyre növekvő
- mennyiségű kódot igényelt, ahogy egyre több és több lehetőség állt rendelkezésre: beállítani
- az adatbázist, a nézetet és a nézet segédeket, az elrendezéseket, bejegyezni a
- bővítményeket, művelet segédeket és a többi.
- </para>
- <para>
- Ezen felül gyakoran igény lehet ugyanazon kód használata a tesztek, ütemezett feladatok vagy
- egy webszolgáltatás rendszertöltéséhez. Miközben lehetséges egyszerűen beilleszteni a
- rendszertöltő állományt, gyakori, hogy bizonyos beállítások környezetre jellemzők – nem
- szükséges az <acronym>MVC</acronym> egy ütemezett feladathoz, vagy az adatbázis réteg egy
- szolgáltatáshoz.
- </para>
- <para>
- A <classname>Zend_Application</classname> célja ennek leegyszerűsítése és az újrahasznosítás
- elősegítése a rendszertöltés <acronym>OOP</acronym> mintákba zárásával.
- </para>
- <para>
- A <classname>Zend_Application</classname> három részre bontható:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <classname>Zend_Application</classname>: betölti a <acronym>PHP</acronym>
- környezetet, beleértve az include_path-t és az automatikus betöltést, illetve
- példányosítja a kért rendszertöltő osztályt.
- </para>
- </listitem>
- <listitem>
- <para>
- <classname>Zend_Application_Bootstrap</classname>: felületeket nyújt a rendszertöltő
- osztályoknak. A <classname>Zend_Application_Bootstrap_Bootstrap</classname> a
- legtöbb rendszertöltővel szemben támasztható igényt kielégítő funkcionalitást nyújt,
- beleértve a függőség-ellenőrző algoritmusokat és a rendszertöltő erőforrások igény
- szerinti betöltését.
- </para>
- </listitem>
- <listitem>
- <para>
- A <classname>Zend_Application_Resource</classname> szabványos, egy rendszertöltő
- példány által igény szerint betölthető erőforrásokhoz nyújt felületet, csakúgy, mint
- több kész megvalósítást.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- A fejlesztők a <classname>Zend_Application_Bootstrap_Bootstrap</classname> kiterjesztésével
- vagy (legkevesebb) a <classname>Zend_Application_Bootstrap_Bootstrapper</classname>
- megvalósításával hozhatnak létre rendszertöltőt alkalmazásukhoz. A belépési pont
- (<filename>public/index.php</filename>, pl.) betölti és példányosítja a
- <classname>Zend_Application</classname>-t
- </para>
- <itemizedlist>
- <listitem>
- <para>
- a pillanatnyi környezet és
- </para>
- </listitem>
- <listitem>
- <para>
- a rendszertöltés beállításainak
- </para>
- </listitem>
- </itemizedlist>
- <para>
- átadásával.
- </para>
- <para>
- Utóbbiak magukban foglalják a rendszertöltő osztályt tartalmazó állomány elérési útját,
- illetve igény szerint:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- további include_path összetevőket;
- </para>
- </listitem>
- <listitem>
- <para>
- további automatikus betöltéshez bejegyzendő névtereket;
- </para>
- </listitem>
- <listitem>
- <para>
- beállítandó <filename>php.ini</filename> értékeket;
- </para>
- </listitem>
- <listitem>
- <para>
- a rendszertöltő osztály nevét (ha nem „Bootstrap”)
- </para>
- </listitem>
- <listitem>
- <para>
- erőforrás előtagat a az elérési utakhoz;
- </para>
- </listitem>
- <listitem>
- <para>
- használandó erőforrásokat (az osztály neve vagy rövid név szerint);
- </para>
- </listitem>
- <listitem>
- <para>
- további elérési utakat konfigurációs állományok betöltéséhez, illetve
- </para>
- </listitem>
- <listitem>
- <para>
- további konfigurációs beállításokat.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- A beállítások érkezhetnek egy tömbben, egy <classname>Zend_Config</classname> objektumban
- vagy egy konfigurációs állomány elérési útja képében.
- </para>
- <sect2 id="zend.application.theory-of-operation.bootstrap">
- <title>Rendszertöltés</title>
- <para>
- A <classname>Zend_Application</classname> felelősségi körébe tartozik az alkalmazás
- rendszertöltőjének végrehajtása is. Egy rendszertöltőnek legkevesebb meg kell
- valósítania <classname>Zend_Application_Bootstrap_Bootstrapper</classname>-t, mely
- a következő <acronym>API</acronym>-t határozza meg:
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Application_Bootstrap_Bootstrapper
- {
- public function __construct($application);
- public function setOptions(array $options);
- public function getApplication();
- public function getEnvironment();
- public function getClassResources();
- public function getClassResourceNames();
- public function bootstrap($resource = null);
- public function run();
- }
- ]]></programlisting>
- <para>
- Ez az <acronym>API</acronym> lehetővé teszi a rendszertöltőnek a környezet és
- beállítások fogadását az alkalmazás objektumtól, hogy jelentsen az erőforrásokról,
- melyek indításáért felelős, majd betöltse és futtassa az alkalmazást.
- </para>
- <para>
- A felület megvalósítható önállóan, lehetőség van a
- <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> kiterjesztésére
- vagy a <classname>Zend_Application_Bootstrap_Bootstrap</classname> használatára.
- </para>
- <para>
- Ezek mellett egy sor más dolog is van, mellyel érdemes megismerkedni.
- </para>
- <sect3 id="zend.application.theory-of-operation.bootstrap.resource-methods">
- <title>Erőforrás tagfüggvények</title>
- <para>
- A <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> megvalósítás
- egy egyszerű egyezményt nyújt erőforrás tagfüggvények meghatározására. Minden védett
- tagfüggvény, mely az <emphasis>_init</emphasis> előtaggal kezdődik, erőforrás
- tagfüggvénynek számít.
- </para>
- <para>
- Egy adott erőforrás tagfüggvény betöltéséhez a <methodname>bootstrap()</methodname>
- metódus használatos az erőforrás nevének megadásával. A név a tagfüggvény neve az
- <emphasis>_init</emphasis> előtag elhagyásával.
- </para>
- <para>
- Több tagfüggvény betöltéséhez egy tömböt kell átadni, az összeséhez pedig semmit.
- </para>
- <para>
- Vegyük a következő rendszertöltő osztályt:
- </para>
- <programlisting language="php"><![CDATA[
- class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
- {
- protected function _initFoo()
- {
- // ...
- }
- protected function _initBar()
- {
- // ...
- }
- protected function _initBaz()
- {
- // ...
- }
- }
- ]]></programlisting>
- <para>
- Az <methodname>_initFoo()</methodname> tagfüggvény betöltéséhez a következő a
- teendő:
- </para>
- <programlisting language="php"><![CDATA[
- $bootstrap->bootstrap('foo');
- ]]></programlisting>
- <para>
- Az <methodname>_initFoo()</methodname> és az <methodname>_initBar()</methodname>
- betöltéséhez a következő:
- </para>
- <programlisting language="php"><![CDATA[
- $bootstrap->bootstrap(array('foo', 'bar'));
- ]]></programlisting>
- <para>
- Az öszes betöltéséhez a <methodname>bootstrap()</methodname> argumentumok nélkül
- hívandó:
- </para>
- <programlisting language="php"><![CDATA[
- $bootstrap->bootstrap();
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.application.theory-of-operation.bootstrap.resource-plugins">
- <title>Bootstraps that use resource plugins</title>
- <para>
- To make your bootstraps more re-usable, we have provided the
- ability to push your resources into resource plugin classes.
- This allows you to mix and match resources simply via
- configuration. We will cover <link
- linkend="zend.application.theory-of-operation.resources">how
- to create resources</link> later; in
- this section we will show you how to utilize them only.
- </para>
- <para>
- If your bootstrap should be capable of using resource plugins,
- you will need to implement an additional interface,
- <classname>Zend_Application_Bootstrap_ResourceBootstrapper</classname>.
- This interface defines an <acronym>API</acronym> for locating, registering, and
- loading resource plugins:
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Application_Bootstrap_ResourceBootstrapper
- {
- public function registerPluginResource($resource, $options = null);
- public function unregisterPluginResource($resource);
- public function hasPluginResource($resource);
- public function getPluginResource($resource);
- public function getPluginResources();
- public function getPluginResourceNames();
- public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader);
- public function getPluginLoader();
- }
- ]]></programlisting>
- <para>
- Resource plugins basically provide the ability to create
- resource intializers that can be re-used between applications.
- This allows you to keep your actual bootstrap relatively clean,
- and to introduce new resources without needing to touch your
- bootstrap itself.
- </para>
- <para>
- <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> (and
- <classname>Zend_Application_Bootstrap_Bootstrap</classname> by extension)
- implement this interface as well, allowing you to utilize
- resource plugins.
- </para>
- <para>
- To utilize resource plugins, you must specify them in the
- options passed to the application object and/or bootstrap. These
- options may come from a configuration file, or be passed in
- manually. Options will be of key to options pairs, with the key
- representing the resource name. The resource name will be the
- segment following the class prefix. For example, the resources
- shipped with Zend Framework have the class prefix
- "<classname>Zend_Application_Resource_</classname>"; anything following this would
- be the name of the resource. As an example,
- </para>
- <programlisting language="php"><![CDATA[
- $application = new Zend_Application(APPLICATION_ENV, array(
- 'resources' => array(
- 'FrontController' => array(
- 'controllerDirectory' => APPLICATION_PATH . '/controllers',
- ),
- ),
- ));
- ]]></programlisting>
- <para>
- This indicates that the "FrontController" resource should be
- used, with the options specified.
- </para>
- <para>
- If you begin writing your own resource plugins, or utilize
- third-party resource plugins, you will need to tell your
- bootstrap where to look for them. Internally, the bootstrap
- utilizes <classname>Zend_Loader_PluginLoader</classname>, so you will only
- need to indicate the common class prefix an path pairs.
- </para>
- <para>
- As an example, let's assume you have custom resource plugins in
- <filename>APPLICATION_PATH/resources/</filename> and that they share the
- common class prefix of <classname>My_Resource</classname>. You would then
- pass that information to the application object as follows:
- </para>
- <programlisting language="php"><![CDATA[
- $application = new Zend_Application(APPLICATION_ENV, array(
- 'pluginPaths' => array(
- 'My_Resource' => APPLICATION_PATH . '/resources/',
- ),
- 'resources' => array(
- 'FrontController' => array(
- 'controllerDirectory' => APPLICATION_PATH . '/controllers',
- ),
- ),
- ));
- ]]></programlisting>
- <para>
- You would now be able to use resources from that directory.
- </para>
- <para>
- Just like resource methods, you use the <methodname>bootstrap()</methodname>
- method to execute resource plugins. Just like with resource
- methods, you can specify either a single resource plugin,
- multiple plugins (via an array), or all plugins. Additionally,
- you can mix and match to execute resource methods as well.
- </para>
- <programlisting language="php"><![CDATA[
- // Execute one:
- $bootstrap->bootstrap('FrontController');
- // Execute several:
- $bootstrap->bootstrap(array('FrontController', 'Foo'));
- // Execute all resource methods and plugins:
- $bootstrap->bootstrap();
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.application.theory-of-operation.bootstrap.registry">
- <title>Resource Registry</title>
- <para>
- Many, if not all, of your resource methods or plugins will
- initialize objects, and in many cases, these objects will be
- needed elsewhere in your application. How can you access them?
- </para>
- <para>
- <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
- provides a local registry for these objects. To store your
- objects in them, you simply return them from your resources.
- </para>
- <para>
- For maximum flexibility, this registry is referred to as a
- "container" internally; its only requirements are that it is an
- object. Resources are then registered as properties named after
- the resource name. By default, an instance of
- <classname>Zend_Registry</classname> is used, but you may also specify any
- other object you wish. The methods <methodname>setContainer()</methodname>
- and <methodname>getContainer()</methodname> may be used to manipulate the
- container itself. <methodname>getResource($resource)</methodname> can be
- used to fetch a given resource from the container, and
- <methodname>hasResource($resource)</methodname> to check if the resource has
- actually been registered.
- </para>
- <para>
- As an example, consider a basic view resource:
- </para>
- <programlisting language="php"><![CDATA[
- class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
- {
- protected function _initView()
- {
- $view = new Zend_View();
- // more initialization...
- return $view;
- }
- }
- ]]></programlisting>
- <para>
- You can then check for it and/or fetch it as follows:
- </para>
- <programlisting language="php"><![CDATA[
- // Using the has/getResource() pair:
- if ($bootstrap->hasResource('view')) {
- $view = $bootstrap->getResource('view');
- }
- // Via the container:
- $container = $bootstrap->getContainer();
- if (isset($container->view)) {
- $view = $container->view;
- }
- ]]></programlisting>
- <para>
- Please note that the registry and also the container is not global. This
- means that you need access to the bootstrap in order to fetch
- resources. <classname>Zend_Application_Bootstrap_Bootstrap</classname>
- provides some convenience for this: during its
- <methodname>run()</methodname> execution, it registers itself as the front
- controller parameter "bootstrap", which allows you to fetch it
- from the router, dispatcher, plugins, and action controllers.
- </para>
- <para>
- As an example, if you wanted access to the view resource from
- above within your action controller, you could do the following:
- </para>
- <programlisting language="php"><![CDATA[
- class FooController extends Zend_Controller_Action
- {
- public function init()
- {
- $bootstrap = $this->getInvokeArg('bootstrap');
- $view = $bootstrap->getResource('view');
- // ...
- }
- }
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.application.theory-of-operation.bootstrap.dependency-tracking">
- <title>Dependency Tracking</title>
- <para>
- In addition to executing resource methods and plugins, it's
- necessary to ensure that these are executed once and once
- only; these are meant to bootstrap an application, and
- executing multiple times can lead to resource overhead.
- </para>
- <para>
- At the same time, some resources may depend on other
- resources being executed. To solve these two issues,
- <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
- provides a simple, effective mechanism for dependency
- tracking.
- </para>
- <para>
- As noted previously, all resources -- whether methods or plugins
- -- are bootstrapped by calling <methodname>bootstrap($resource)</methodname>,
- where <varname>$resource</varname> is the name of a resource, an array
- of resources, or, left empty, indicates all resources should be
- run.
- </para>
- <para>
- If a resource depends on another resource, it should call
- <methodname>bootstrap()</methodname> within its code to ensure that resource
- has been executed. Subsequent calls to it will then be ignored.
- </para>
- <para>
- In a resource method, such a call would look like this:
- </para>
- <programlisting language="php"><![CDATA[
- class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
- {
- protected function _initRequest()
- {
- // Ensure the front controller is initialized
- $this->bootstrap('FrontController');
- // Retrieve the front controller from the bootstrap registry
- $front = $this->getResource('FrontController');
- $request = new Zend_Controller_Request_Http();
- $request->setBaseUrl('/foo');
- $front->setRequest($request);
- // Ensure the request is stored in the bootstrap registry
- return $request;
- }
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.application.theory-of-operation.resources">
- <title>Resource Plugins</title>
- <para>
- <link
- linkend="zend.application.theory-of-operation.bootstrap.resource-plugins">As noted
- previously</link>, a good way to create re-usable bootstrap resources and to
- offload much of your coding to discrete classes is to utilize resource
- plugins. While Zend Framework ships with a number of standard
- resource plugins, the intention is that developers should write
- their own to encapsulate their own initialization needs.
- </para>
- <para>
- Resources need only implement
- <classname>Zend_Application_Resource_Resource</classname>, or, more simply
- still, extend
- <classname>Zend_Application_Resource_ResourceAbstract</classname>. The basic
- interface is simply this:
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Application_Resource_Resource
- {
- public function __construct($options = null);
- public function setBootstrap(
- Zend_Application_Bootstrap_Bootstrapper $bootstrap
- );
- public function getBootstrap();
- public function setOptions(array $options);
- public function getOptions();
- public function init();
- }
- ]]></programlisting>
- <para>
- The interface defines simply that a resource should accept options
- to the constructor, have mechanisms for setting and retrieving
- options, have mechanisms for setting and retrieving the bootstrap
- object, and an initialization method.
- </para>
- <para>
- As an example, let's assume you have a common view intialization you
- use in your applications. You have a common doctype, <acronym>CSS</acronym> and
- JavaScript, and you want to be able to pass in a base document title
- via configuration. Such a resource might look like this:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Resource_View extends Zend_Application_Resource_ResourceAbstract
- {
- protected $_view;
- public function init()
- {
- // Return view so bootstrap will store it in the registry
- return $this->getView();
- }
- public function getView()
- {
- if (null === $this->_view) {
- $options = $this->getOptions();
- $title = '';
- if (array_key_exists('title', $options)) {
- $title = $options['title'];
- unset($options['title']);
- }
- $view = new Zend_View($options);
- $view->doctype('XHTML1_STRICT');
- $view->headTitle($title);
- $view->headLink()->appendStylesheet('/css/site.css');
- $view->headScript()->appendfile('/js/analytics.js');
- $viewRenderer =
- Zend_Controller_Action_HelperBroker::getStaticHelper(
- 'ViewRenderer'
- );
- $viewRenderer->setView($view);
- $this->_view = $view;
- }
- return $this->_view;
- }
- }
- ]]></programlisting>
- <para>
- As long as you register the prefix path for this resource plugin,
- you can then use it in your application. Even better, because it
- uses the plugin loader, you are effectively overriding the shipped
- "View" resource plugin, ensuring that your own is used instead.
- </para>
- </sect2>
- </sect1>
|