| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.loader.pluginloader">
- <title>Chargeur de Plugins</title>
- <para>
- Zend Framework vous propose l'utilisation de composants "pluggables", que vous créez
- vous même. Ceux-ci ne sont pas forcément dans l'include_path. De même, ils ne suivent pas
- forcément les mêmes règles de nommage que les composants de Zend
- Framework.<classname>Zend_Loader_PluginLoader</classname> propose une solution à ce
- problème.
- </para>
- <para>
- <code>PluginLoader</code> suit la convention "une classe par fichier" et les tirets
- bas sont utilisés comme séparateurs de dossiers. Il accepte aussi qu'un préfixe optionnel
- lui soit passé, afin de charger une classe. Tous les chemins sont analysés en ordre LIFO.
- Grâce à ces deux spécificités, vous pouvez "namespacer" vos plugins, et écraser les plugins
- enregistrés plus tôt.
- </para>
- <sect2 id="zend.loader.pluginloader.usage">
- <title>Utilisation basique</title>
- <para>
- Même si nous parlons de "plugins", ce n'est pas réservé aux plugins de contrôleur
- frontal, mais bien à toute classe étant utilisée avec Zend Framework. Imaginons une
- structure de répertoires comme suit, dans laquelle les dossiers "application" et
- "library" sont dans l'include_path :
- </para>
- <programlisting language="txt"><![CDATA[
- application/
- modules/
- foo/
- views/
- helpers/
- FormLabel.php
- FormSubmit.php
- bar/
- views/
- helpers/
- FormSubmit.php
- library/
- Zend/
- View/
- Helper/
- FormLabel.php
- FormSubmit.php
- FormText.php
- ]]></programlisting>
- <para>
- Maintenant créons un chargeur de plugins pour utiliser les différentes classes
- d'aides de vue :
- </para>
- <programlisting language="php"><![CDATA[
- $loader = new Zend_Loader_PluginLoader();
- $loader->addPrefixPath('Zend_View_Helper',
- 'Zend/View/Helper/')
- ->addPrefixPath('Foo_View_Helper',
- 'application/modules/foo/views/helpers')
- ->addPrefixPath('Bar_View_Helper',
- 'application/modules/bar/views/helpers');
- ]]></programlisting>
- <para>
- Il devient alors possible de charger une aide de vue en spécifiant juste le nom de
- sa classe :
- </para>
- <programlisting language="php"><![CDATA[
- // charge l'aide 'FormText' :
- $formTextClass = $loader->load('FormText');
- // 'Zend_View_Helper_FormText'
- // charge l'aide 'FormLabel' :
- $formLabelClass = $loader->load('FormLabel');
- // 'Foo_View_Helper_FormLabel'
- // charge l'aide 'FormSubmit' :
- $formSubmitClass = $loader->load('FormSubmit');
- // 'Bar_View_Helper_FormSubmit'
- ]]></programlisting>
- <para>Une fois chargée, la classe devient instanciable.</para>
- <note>
- <title>Plusieurs dossiers peuvent être assignés à un même préfixe</title>
- <para>
- Vous pouvez "namespacer" vos composants en enregistrant plusieurs chemins pour
- un même préfixe.<classname>Zend_Loader_PluginLoader</classname> cherchera alors en
- ordre LIFO (dernier arrivé, premier sorti). Ceci est pratique pour court-circuiter
- ses composants et utiliser ceux en incubateur, par exemple.
- </para>
- </note>
- <note>
- <title>Paramétrage des chemins dans le constructeur</title>
- <para>
- En constructeur, passez un tableau de paires prefix / path ou prefix / paths
- -- plusieurs dossiers par préfixe :
- </para>
- <programlisting language="php"><![CDATA[
- $loader = new Zend_Loader_PluginLoader(array(
- 'Zend_View_Helper' => 'Zend/View/Helper/',
- 'Foo_View_Helper' => 'application/modules/foo/views/helpers',
- 'Bar_View_Helper' => 'application/modules/bar/views/helpers'
- ));
- ]]></programlisting>
- </note>
- <para>
- <classname>Zend_Loader_PluginLoader</classname> peut aussi permettre de partager
- des plugins grâce au registre. Indiquez le nom du registre de cette manière :
- </para>
- <programlisting language="php"><![CDATA[
- // Stocke les plugins dans le registre à l'index 'foobar':
- $loader = new Zend_Loader_PluginLoader(array(), 'foobar');
- ]]></programlisting>
- <para>
- Si un autre composant instancie le <code>PluginLoader</code> en utilisant le même
- nom de registre, alors tous les chemins et plugins déjà chargés seront
- disponibles.
- </para>
- </sect2>
- <sect2 id="zend.loader.pluginloader.paths">
- <title>Manipulation des chemins des Plugins</title>
- <para>
- Pour afficher ou supprimer des chemins déjà enregistrés, utilisez l'une des
- méthodes suivantes :
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>getPaths($prefix = null)</methodname> retourne les chemin sous la forme
- prefix / path si <varname>$prefix</varname> n'est pas renseigné. Sinon, ce sont les
- chemins enregistrés pour le préfixe en question qui sont renvoyés.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearPaths($prefix = null)</methodname> va effacer tous les chemins. Si
- <varname>$prefix</varname> est passé, ce sont les chemins correspondants à ce préfixe
- qui seront supprimés.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>removePrefixPath($prefix, $path = null)</methodname> permet de supprimer
- un chemin précis, d'un préfixe spécifié. Si <varname>$path</varname> n'est pas
- renseigné, tous les chemins du préfixe seront effacés.
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.loader.pluginloader.checks">
- <title>Test des Plugins et récupération des noms de classe</title>
- <para>
- Lorsque vous voulez savoir si une classe de plugin a été chargée,
- <methodname>isLoaded()</methodname> prend en paramètre le nom du plugin, et retourne sont
- statut.
- </para>
- <para>
- Une autre utilisation de <code>PluginLoader</code> peut être de récupérer le nom
- des classes des plugins chargés.<methodname>getClassName()</methodname> vous le permet. Utilisée en
- conjonction avec <methodname>isLoaded()</methodname>, vous pouvez écrire par exemple ceci :
- </para>
- <programlisting language="php"><![CDATA[
- if ($loader->isLoaded('Adapter')) {
- $class = $loader->getClassName('Adapter');
- $adapter = call_user_func(array($class, 'getInstance'));
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.loader.pluginloader.performance">
- <title>Obtenir de meilleures performances avec les Plugins</title>
- <para>
- Le chargement des plugins peut être une opération consommatrice en ressources. En
- interne, il doit parcourir chaque préfixe, ainsi que chaque chemin dans ce préfixe
- jusqu'à ce qu'il trouve un fichier qui correspond - et qui définit de plus la classe
- voulue. Dans le cas où le fichier existe mais ne défini pas la classe, une erreur sera
- ajouté à la pile d'erreur <acronym>PHP</acronym>, opération qui est elle aussi consommatrice. La question
- qui vient à l'esprit est : comment maintenir la flexibilité des plugins et la
- performance ?
- </para>
- <para>
- <classname>Zend_Loader_PluginLoader</classname> offre une fonctionnalité intégrée
- pour ce cas, un fichier de cache des inclusions de classe. Quand il est activé, ceci
- crée un fichier qui contient toutes les inclusions qui ont fonctionnées et qui peuvent
- donc être appelées dans votre fichier d'initialisation. En utilisant ceci, vous pouvez
- considérablement accroître les performances de vos serveurs de production.
- </para>
- <example id="zend.loader.pluginloader.performance.example">
- <title>Utilisation du fichier de cache des inclusions de classe de
- PluginLoader</title>
- <para>
- Pour utiliser le fichier de cache des inclusions de classe, collez simplement
- le code suivant dans votre fichier d'initialisation :
- </para>
- <programlisting language="php"><![CDATA[
- $classFileIncCache = APPLICATION_PATH . '/../data/pluginLoaderCache.php';
- if (file_exists($classFileIncCache)) {
- include_once $classFileIncCache;
- }
- Zend_Loader_PluginLoader::setIncludeFileCache($classFileIncCache);
- ]]></programlisting>
- <para>
- Évidemment, le chemin et le fichier varieront en fonction de vos besoins. Ce
- code doit intervenir aussi vite que possible, pour s'assurer que tous les composants
- à base de plugins pourront l'utiliser.
- </para>
- <para>
- En cours du développement, vous pouvez souhaiter désactiver le cache. Une
- méthode permettant ceci est d'utiliser une clé de configuration pour déterminer ou
- non si le chargeur de plugins doit mettre les informations en cache.
- </para>
- <programlisting language="php"><![CDATA[
- $classFileIncCache = APPLICATION_PATH . '/../data/pluginLoaderCache.php';
- if (file_exists($classFileIncCache)) {
- include_once $classFileIncCache;
- }
- if ($config->enablePluginLoaderCache) {
- Zend_Loader_PluginLoader::setIncludeFileCache($classFileIncCache);
- }
- ]]></programlisting>
- <para>
- Cette technique vous permet de restreindre les modifications au seul fichier
- de configuration plutôt que dans votre code.
- </para>
- </example>
- </sect2>
- </sect1>
|