[ZF-10089] Zend_Log
[zend.git] / documentation / manual / fr / module_specs / Zend_Application-TheoryOfOperation.xml
bloba61db2448ea9154d4489c110b48f21f41e00fb90
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- EN-Revision: 20763 -->
3 <!-- Reviewed: no -->
4 <sect1 id="zend.application.theory-of-operation">
5     <title>Théorie générale</title>
7     <para>
8         Monter une application <acronym>MVC</acronym> configurée et prête à être lancée requière de
9         plus en plus de code au fur et à mesure de l'ajout de fonctionnalités&#160;: monter une base
10         de données, configurer la vue et ses aides, les layouts, enregistrer des plugins, des aides
11         d'action et bien plus encore...
12     </para>
14     <para>
15         Aussi, vous réutiliserez souvent le même code dans vos tests, dans une tâche cron ou
16         encore un service. Il est certes possible d'inclure le script de bootstrap dans de tels cas,
17         mais souvent des variables seront dépendantes de l'environnement. Par exemple, vous n'aurez
18         pas besoin de <acronym>MVC</acronym> dans une tâche cron, ou alors vous aurez juste besoin
19         de l'accès à la base de données dans un script de service.
20     </para>
22     <para>
23         <classname>Zend_Application</classname> a pour but de simplifier ces processus et de
24         promouvoir la réutilisabilité de code en encapsulant les étages de définition du bootstrap
25         en concepts orientés objet (<acronym>OO</acronym>).
26     </para>
28     <para><classname>Zend_Application</classname> se décompose en 3 parties&#160;:</para>
30     <itemizedlist>
31         <listitem>
32             <para>
33                 <classname>Zend_Application</classname> charge l'environnement
34                 <acronym>PHP</acronym>, à savoir les include_paths et les autoloads, et instancie
35                 la classe de bootstrap demandée.
36             </para>
37         </listitem>
39         <listitem>
40             <para>
41                 <classname>Zend_Application_Bootstrap</classname> regroupe les interfaces pour les
42                 classes de bootstrap. <classname>Zend_Application_Bootstrap_Bootstrap</classname>
43                 propose des fonctionnalités de base concernant l'amorçage (le bootstrap), à savoir
44                 des algorithmes de vérification des dépendances et la possibilité de charger des
45                 ressources à la demande.
46             </para>
47         </listitem>
49         <listitem>
50             <para>
51                 <classname>Zend_Application_Resource</classname> est une interface pour les
52                 ressources de bootstrap qui peuvent être chargées à la demande depuis les instances
53                 de bootstrap.
54             </para>
55         </listitem>
56     </itemizedlist>
58     <para>
59         Les développeurs créent une classe de bootstrap pour leur application en étendant
60         <classname>Zend_Application_Bootstrap_Bootstrap</classname> ou en implémentant (au minimum)
61         <classname>Zend_Application_Bootstrap_Bootstrapper</classname>. Le point d'entrée
62         (<filename>public/index.php</filename>) chargera <classname>Zend_Application</classname>
63         en l'instanciant et en lui passant&#160;:
64     </para>
66     <itemizedlist>
67         <listitem>
68             <para>L'environnement courant</para>
69         </listitem>
71         <listitem>
72             <para>Des options de bootstrapping</para>
73         </listitem>
74     </itemizedlist>
76     <para>
77         Les options de bootstrap incluent le chemin vers le fichier contenant la classe de
78         bootstrap, et optionnellement&#160;:
79     </para>
81     <itemizedlist>
82         <listitem>
83             <para>Des include_paths supplémentaires</para>
84         </listitem>
86         <listitem>
87             <para>Des espaces de nom d'autoload à enregistrer</para>
88         </listitem>
90         <listitem>
91             <para>Des paramètres <filename>php.ini</filename> à initialiser</para>
92         </listitem>
94         <listitem>
95             <para>Le nom de la classe pour le bootstrap (sinon "Bootstrap" sera utilisée)</para>
96         </listitem>
98         <listitem>
99             <para>Des paires préfixe&#160;/&#160;chemin pour les ressources à utiliser</para>
100         </listitem>
102         <listitem>
103             <para>N'importe quelle ressource à utiliser (nom de classe ou nom court)</para>
104         </listitem>
106         <listitem>
107             <para>Des chemins additionnels vers un fichier de configuration à charger</para>
108         </listitem>
110         <listitem>
111             <para>Des options de configuration supplémentaires</para>
112         </listitem>
113     </itemizedlist>
115     <para>
116         Les options peuvent être un tableau, un objet <classname>Zend_Config</classname>, ou
117         le chemin vers un fichier de configuration.
118     </para>
120     <sect2 id="zend.application.theory-of-operation.bootstrap">
121         <title>Bootstrapping</title>
123         <para>
124             <classname>Zend_Application</classname>'s second area of responsibility is
125             executing the application bootstrap. Bootstraps minimally need to
126             implement <classname>Zend_Application_Bootstrap_Bootstrapper</classname>,
127             which defines the following <acronym>API</acronym>:
128         </para>
130         <programlisting language="php"><![CDATA[
131 interface Zend_Application_Bootstrap_Bootstrapper
133     public function __construct($application);
134     public function setOptions(array $options);
135     public function getApplication();
136     public function getEnvironment();
137     public function getClassResources();
138     public function getClassResourceNames();
139     public function bootstrap($resource = null);
140     public function run();
142 ]]></programlisting>
144         <para>
145             This <acronym>API</acronym> allows the bootstrap to accept the environment and
146             configuration from the application object, report the resources its
147             responsible for bootstrapping, and then bootstrap and run the
148             application.
149         </para>
151         <para>
152             You can implement this interface on your own, extend
153             <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>, or use
154             <classname>Zend_Application_Bootstrap_Bootstrap</classname>.
155         </para>
157         <para>
158             Besides this functionality, there are a number of other areas of
159             concern you should familiarize yourself with.
160         </para>
162         <sect3 id="zend.application.theory-of-operation.bootstrap.resource-methods">
163             <title>Resource Methods</title>
165             <para>
166                 The <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
167                 implementation provides a simple convention for defining class
168                 resource methods. Any protected method beginning with a name
169                 prefixed with <emphasis>_init</emphasis> will be considered a resource
170                 method.
171             </para>
173             <para>
174                 To bootstrap a single resource method, use the
175                 <methodname>bootstrap()</methodname> method, and pass it the name of the
176                 resource. The name will be the method name minus the
177                 <emphasis>_init</emphasis> prefix.
178             </para>
180             <para>
181                 To bootstrap several resource methods, pass an array of names.
182                 Too bootstrap all resource methods, pass nothing.
183             </para>
185             <para>
186                 Take the following bootstrap class:
187             </para>
189             <programlisting language="php"><![CDATA[
190 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
192     protected function _initFoo()
193     {
194         // ...
195     }
197     protected function _initBar()
198     {
199         // ...
200     }
202     protected function _initBaz()
203     {
204         // ...
205     }
207 ]]></programlisting>
209             <para>
210                 To bootstrap just the <methodname>_initFoo()</methodname> method, do the
211                 following:
212             </para>
214             <programlisting language="php"><![CDATA[
215 $bootstrap->bootstrap('foo');
216 ]]></programlisting>
218             <para>
219                 To bootstrap the <methodname>_initFoo()</methodname> and
220                 <methodname>_initBar()</methodname> methods, do the following:
221             </para>
223             <programlisting language="php"><![CDATA[
224 $bootstrap->bootstrap(array('foo', 'bar'));
225 ]]></programlisting>
227             <para>
228                 To bootstrap all resource methods, call <methodname>bootstrap()</methodname>
229                 with no arguments:
230             </para>
232             <programlisting language="php"><![CDATA[
233 $bootstrap->bootstrap();
234 ]]></programlisting>
235         </sect3>
237         <sect3 id="zend.application.theory-of-operation.bootstrap.resource-plugins">
238             <title>Bootstraps that use resource plugins</title>
240             <para>
241                 To make your bootstraps more re-usable, we have provided the
242                 ability to push your resources into resource plugin classes.
243                 This allows you to mix and match resources simply via
244                 configuration. We will cover <link
245                     linkend="zend.application.theory-of-operation.resources">how
246                     to create resources</link> later; in
247                 this section we will show you how to utilize them only.
248             </para>
250             <para>
251                 If your bootstrap should be capable of using resource plugins,
252                 you will need to implement an additional interface,
253                 <classname>Zend_Application_Bootstrap_ResourceBootstrapper</classname>.
254                 This interface defines an <acronym>API</acronym> for locating, registering, and
255                 loading resource plugins:
256             </para>
258         <programlisting language="php"><![CDATA[
259 interface Zend_Application_Bootstrap_ResourceBootstrapper
261     public function registerPluginResource($resource, $options = null);
262     public function unregisterPluginResource($resource);
263     public function hasPluginResource($resource);
264     public function getPluginResource($resource);
265     public function getPluginResources();
266     public function getPluginResourceNames();
267     public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader);
268     public function getPluginLoader();
270 ]]></programlisting>
272             <para>
273                 Resource plugins basically provide the ability to create
274                 resource intializers that can be re-used between applications.
275                 This allows you to keep your actual bootstrap relatively clean,
276                 and to introduce new resources without needing to touch your
277                 bootstrap itself.
278             </para>
280             <para>
281                 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname> (and
282                 <classname>Zend_Application_Bootstrap_Bootstrap</classname> by extension)
283                 implement this interface as well, allowing you to utilize
284                 resource plugins.
285             </para>
287             <para>
288                 To utilize resource plugins, you must specify them in the
289                 options passed to the application object and/or bootstrap. These
290                 options may come from a configuration file, or be passed in
291                 manually. Options will be of key to options pairs, with the key
292                 representing the resource name. The resource name will be the
293                 segment following the class prefix. For example, the resources
294                 shipped with Zend Framework have the class prefix
295                 "<classname>Zend_Application_Resource_</classname>"; anything following this would
296                 be the name of the resource. As an example,
297             </para>
299             <programlisting language="php"><![CDATA[
300 $application = new Zend_Application(APPLICATION_ENV, array(
301     'resources' => array(
302         'FrontController' => array(
303             'controllerDirectory' => APPLICATION_PATH . '/controllers',
304         ),
305     ),
307 ]]></programlisting>
309             <para>
310                 This indicates that the "FrontController" resource should be
311                 used, with the options specified.
312             </para>
314             <para>
315                 If you begin writing your own resource plugins, or utilize
316                 third-party resource plugins, you will need to tell your
317                 bootstrap where to look for them. Internally, the bootstrap
318                 utilizes <classname>Zend_Loader_PluginLoader</classname>, so you will only
319                 need to indicate the common class prefix an path pairs.
320             </para>
322             <para>
323                 As an example, let's assume you have custom resource plugins in
324                 <filename>APPLICATION_PATH/resources/</filename> and that they share the
325                 common class prefix of <classname>My_Resource</classname>. You would then
326                 pass that information to the application object as follows:
327             </para>
329             <programlisting language="php"><![CDATA[
330 $application = new Zend_Application(APPLICATION_ENV, array(
331     'pluginPaths' => array(
332         'My_Resource' => APPLICATION_PATH . '/resources/',
333     ),
334     'resources' => array(
335         'FrontController' => array(
336             'controllerDirectory' => APPLICATION_PATH . '/controllers',
337         ),
338     ),
340 ]]></programlisting>
342             <para>
343                 You would now be able to use resources from that directory.
344             </para>
346             <para>
347                 Just like resource methods, you use the <methodname>bootstrap()</methodname>
348                 method to execute resource plugins. Just like with resource
349                 methods, you can specify either a single resource plugin,
350                 multiple plugins (via an array), or all plugins. Additionally,
351                 you can mix and match to execute resource methods as well.
352             </para>
354             <programlisting language="php"><![CDATA[
355 // Execute one:
356 $bootstrap->bootstrap('FrontController');
358 // Execute several:
359 $bootstrap->bootstrap(array('FrontController', 'Foo'));
361 // Execute all resource methods and plugins:
362 $bootstrap->bootstrap();
363 ]]></programlisting>
364         </sect3>
366         <sect3 id="zend.application.theory-of-operation.bootstrap.registry">
367             <title>Resource Registry</title>
369             <para>
370                 Many, if not all, of your resource methods or plugins will
371                 initialize objects, and in many cases, these objects will be
372                 needed elsewhere in your application. How can you access them?
373             </para>
375             <para>
376                 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
377                 provides a local registry for these objects. To store your
378                 objects in them, you simply return them from your resources.
379             </para>
381             <para>
382                 For maximum flexibility, this registry is referred to as a
383                 "container" internally; its only requirements are that it is an
384                 object. Resources are then registered as properties named after
385                 the resource name. By default, an instance of
386                 <classname>Zend_Registry</classname> is used, but you may also specify any
387                 other object you wish. The methods <methodname>setContainer()</methodname>
388                 and <methodname>getContainer()</methodname> may be used to manipulate the
389                 container itself. <methodname>getResource($resource)</methodname> can be
390                 used to fetch a given resource from the container, and
391                 <methodname>hasResource($resource)</methodname> to check if the resource has
392                 actually been registered.
393             </para>
395             <para>
396                 As an example, consider a basic view resource:
397             </para>
399             <programlisting language="php"><![CDATA[
400 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
402     protected function _initView()
403     {
404         $view = new Zend_View();
405         // more initialization...
407         return $view;
408     }
410 ]]></programlisting>
412             <para>
413                 You can then check for it and/or fetch it as follows:
414             </para>
416             <programlisting language="php"><![CDATA[
417 // Using the has/getResource() pair:
418 if ($bootstrap->hasResource('view')) {
419     $view = $bootstrap->getResource('view');
422 // Via the container:
423 $container = $bootstrap->getContainer();
424 if (isset($container->view)) {
425     $view = $container->view;
427 ]]></programlisting>
429             <para>
430                 Please note that the registry and also the container is not global. This
431                 means that you need access to the bootstrap in order to fetch
432                 resources. <classname>Zend_Application_Bootstrap_Bootstrap</classname>
433                 provides some convenience for this: during its
434                 <methodname>run()</methodname> execution, it registers itself as the front
435                 controller parameter "bootstrap", which allows you to fetch it
436                 from the router, dispatcher, plugins, and action controllers.
437             </para>
439             <para>
440                 As an example, if you wanted access to the view resource from
441                 above within your action controller, you could do the following:
442             </para>
444             <programlisting language="php"><![CDATA[
445 class FooController extends Zend_Controller_Action
447     public function init()
448     {
449         $bootstrap = $this->getInvokeArg('bootstrap');
450         $view = $bootstrap->getResource('view');
451         // ...
452     }
454 ]]></programlisting>
455         </sect3>
457         <sect3 id="zend.application.theory-of-operation.bootstrap.dependency-tracking">
458             <title>Dependency Tracking</title>
460             <para>
461                 In addition to executing resource methods and plugins, it's
462                 necessary to ensure that these are executed once and once
463                 only; these are meant to bootstrap an application, and
464                 executing multiple times can lead to resource overhead.
465             </para>
467             <para>
468                 At the same time, some resources may depend on other
469                 resources being executed. To solve these two issues,
470                 <classname>Zend_Application_Bootstrap_BootstrapAbstract</classname>
471                 provides a simple, effective mechanism for dependency
472                 tracking.
473             </para>
475             <para>
476                 As noted previously, all resources -- whether methods or plugins
477                 -- are bootstrapped by calling <methodname>bootstrap($resource)</methodname>,
478                 where <varname>$resource</varname> is the name of a resource, an array
479                 of resources, or, left empty, indicates all resources should be
480                 run.
481             </para>
483             <para>
484                 If a resource depends on another resource, it should call
485                 <methodname>bootstrap()</methodname> within its code to ensure that resource
486                 has been executed. Subsequent calls to it will then be ignored.
487             </para>
489             <para>
490                 In a resource method, such a call would look like this:
491             </para>
493             <programlisting language="php"><![CDATA[
494 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
496     protected function _initRequest()
497     {
498         // Ensure the front controller is initialized
499         $this->bootstrap('FrontController');
501         // Retrieve the front controller from the bootstrap registry
502         $front = $this->getResource('FrontController');
504         $request = new Zend_Controller_Request_Http();
505         $request->setBaseUrl('/foo');
506         $front->setRequest($request);
508         // Ensure the request is stored in the bootstrap registry
509         return $request;
510     }
512 ]]></programlisting>
513         </sect3>
514     </sect2>
516     <sect2 id="zend.application.theory-of-operation.resources">
517         <title>Resource Plugins</title>
519         <para>
520             <link
521                 linkend="zend.application.theory-of-operation.bootstrap.resource-plugins">As noted
522                 previously</link>, a good way to create re-usable bootstrap resources and to
523             offload much of your coding to discrete classes is to utilize resource
524             plugins. While Zend Framework ships with a number of standard
525             resource plugins, the intention is that developers should write
526             their own to encapsulate their own initialization needs.
527         </para>
529         <para>
530             Resources plugins need only implement
531             <classname>Zend_Application_Resource_Resource</classname>, or, more simply
532             still, extend
533             <classname>Zend_Application_Resource_ResourceAbstract</classname>. The basic
534             interface is simply this:
535         </para>
537         <programlisting language="php"><![CDATA[
538 interface Zend_Application_Resource_Resource
540     public function __construct($options = null);
541     public function setBootstrap(
542         Zend_Application_Bootstrap_Bootstrapper $bootstrap
543     );
544     public function getBootstrap();
545     public function setOptions(array $options);
546     public function getOptions();
547     public function init();
549 ]]></programlisting>
551         <para>
552             The interface defines simply that a resource plugin should accept options
553             to the constructor, have mechanisms for setting and retrieving
554             options, have mechanisms for setting and retrieving the bootstrap
555             object, and an initialization method.
556         </para>
558         <para>
559             As an example, let's assume you have a common view intialization you
560             use in your applications. You have a common doctype, <acronym>CSS</acronym> and
561             JavaScript, and you want to be able to pass in a base document title
562             via configuration. Such a resource plugin might look like this:
563         </para>
565         <programlisting language="php"><![CDATA[
566 class My_Resource_View extends Zend_Application_Resource_ResourceAbstract
568     protected $_view;
570     public function init()
571     {
572         // Return view so bootstrap will store it in the registry
573         return $this->getView();
574     }
576     public function getView()
577     {
578         if (null === $this->_view) {
579             $options = $this->getOptions();
580             $title   = '';
581             if (array_key_exists('title', $options)) {
582                 $title = $options['title'];
583                 unset($options['title']);
584             }
586             $view = new Zend_View($options);
587             $view->doctype('XHTML1_STRICT');
588             $view->headTitle($title);
589             $view->headLink()->appendStylesheet('/css/site.css');
590             $view->headScript()->appendfile('/js/analytics.js');
592             $viewRenderer =
593                 Zend_Controller_Action_HelperBroker::getStaticHelper(
594                     'ViewRenderer'
595                 );
596             $viewRenderer->setView($view);
598             $this->_view = $view;
599         }
600         return $this->_view;
601     }
603 ]]></programlisting>
605         <para>
606             As long as you register the prefix path for this resource plugin,
607             you can then use it in your application. Even better, because it
608             uses the plugin loader, you are effectively overriding the shipped
609             "View" resource plugin, ensuring that your own is used instead.
610         </para>
611     </sect2>
612 </sect1>