<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 17175 -->
<!-- Reviewed: no -->
<sect1 id="zend.loader.load">
    <title>Charger les fichiers et les classes dynamiquement</title>

    <para>
        La classe <classname>Zend_Loader</classname> inclut des méthodes afin de vous aider à
        charger des fichiers dynamiquement.
    </para>

    <tip>
        <title>Zend_Loader contre require_once()</title>

        <para>
            Les méthodes <classname>Zend_Loader</classname> sont les meilleures à utiliser si
            le nom de fichier que vous devez charger est variable. Par exemple, s'il est basé sur un
            paramètre de la saisie de l'utilisateur ou un argument de méthode. Si vous chargez un
            fichier ou une classe dont le nom est constant, il n'y a aucun avantage à l'utilisation
            de <classname>Zend_Loader</classname> sur l'utilisation de fonctions de <acronym>PHP</acronym>
            traditionnelles comme <ulink
            url="http://php.net/require_once"><methodname>require_once()</methodname></ulink>.
        </para>
    </tip>

    <sect2 id="zend.loader.load.file">
        <title>Charger des fichiers</title>

        <para>
            La méthode statique <methodname>Zend_Loader::loadFile()</methodname> charge un
            fichier <acronym>PHP</acronym>, qui peut contenir du code <acronym>PHP</acronym> arbitraire. Cette méthode enveloppe la
            fonction <acronym>PHP</acronym> <ulink url="http://php.net/include"><methodname>include()</methodname></ulink>, et
            retournera le booléen <constant>FALSE</constant> si le fichier n'existe pas.
        </para>

        <example id="zend.loader.file.example">
            <title>Exemple d'utilisation de la méthode loadFile()</title>

            <programlisting language="php"><![CDATA[
Zend_Loader::loadFile($filename, $dirs=null, $once=false);
]]></programlisting>
        </example>

        <para>
            L'argument <varname>$filename</varname> définit le nom du fichier à charger, et il ne
            doit contenir aucune information concernant son chemin d'accès. Une vérification de
            sécurité est effectuée sur <varname>$filename</varname>. Le fichier <varname>$filename</varname> ne
            peut contenir que des caractères alphanumérique, des tirets ("-"), des tirets-bas ("_")
            ou des points ("."). Aucune de ces restrictions ne s'applique à l'argument
            <varname>$dirs</varname>.
        </para>

        <para>
            L'argument <varname>$dirs</varname> définit les dossiers où rechercher le fichier. Si
            <constant>NULL</constant>, la recherche s'effectuera uniquement dans les dossiers définis par la
            variable <code>include_path</code>. Si c'est une chaîne ou un tableau, le ou les
            répertoires spécifiés seront scannés, ainsi que les dossiers définis par la variable
            <code>include_path</code>.
        </para>

        <para>
            L'argument <varname>$once</varname> est un booléen. Si <constant>TRUE</constant>,
            <methodname>Zend_Loader::loadFile()</methodname> utilise la fonction <acronym>PHP</acronym> <ulink
            url="http://php.net/include"><methodname>include_once()</methodname></ulink> pour charger le fichier
            sinon la fonction <acronym>PHP</acronym> <ulink url="http://php.net/include"><methodname>include()</methodname></ulink>
            est utilisée.
        </para>
    </sect2>

    <sect2 id="zend.loader.load.class">
        <title>Charger des classes</title>

        <para>
            La méthode statique <methodname>Zend_Loader::loadClass($class, $dirs)</methodname>
            charge un fichier <acronym>PHP</acronym> et vérifie l'existence de la classe.
        </para>

        <example id="zend.loader.load.class.example">
            <title>Exemple d'utilisation de la méthode loadClass()</title>

            <programlisting language="php"><![CDATA[
Zend_Loader::loadClass('Container_Tree',
    array(
        '/home/production/mylib',
        '/home/production/myapp'
    )
);
]]></programlisting>
        </example>

        <para>
            La chaîne spécifiant la classe est convertie en chemin relatif en remplaçant les
            tirets bas ("_") par le séparateur de dossier puis en ajoutant le bloc ".php". Dans
            l'exemple ci-dessus, "Container_Tree" devient "Container\\Tree.php".
        </para>

        <para>
            Si <varname>$dirs</varname> est une chaîne ou un tableau,
            <methodname>Zend_Loader::loadClass()</methodname> va chercher dans les dossiers suivant
            l'ordre donné. Le premier fichier trouvé est chargé. Si le fichier n'existe pas dans les
            dossiers spécifiés <varname>$dirs</varname>, alors la recherche est effectuée dans
            <code>include_path</code> du <acronym>PHP</acronym>.
        </para>

        <para>
            Si le fichier n'est pas trouvé ou que la classe n'existe pas après le chargement,
            <methodname>Zend_Loader::loadClass()</methodname> lèvera une exception
            <classname>Zend_Exception</classname>
        </para>

        <para>
            <methodname>Zend_Loader::loadFile()</methodname> est utilisé pour le chargement,
            donc le nom de la classe ne peut contenir que des caractères alphanumériques et les
            caractères tiret ("-"), tiret bas ("_"), et point (".").
        </para>
    </sect2>

    <sect2 id="zend.loader.load.isreadable">
        <title>Tester si un fichier est lisible</title>

        <para>
            La méthode statique <methodname>Zend_Loader::isReadable($pathname)</methodname>
            retourne <constant>TRUE</constant> si le fichier existe dans le dossier spécifié et qu'il est
            lisible, sinon <constant>FALSE</constant>.
        </para>

        <example id="zend.loader.load.isreadable.example">
            <title>Exemple d'utilisation de la méthode isReadable()</title>

            <programlisting language="php"><![CDATA[
if (Zend_Loader::isReadable($filename)) {
    // puis manipulation avec $filename
}
]]></programlisting>
        </example>

        <para>
            L'argument <varname>$filename</varname> spécifie le nom du fichier à vérifier. Il peut
            contenir des informations concernant le chemin d'accès. Cette méthode enveloppe la
            fonction <acronym>PHP</acronym> <ulink url="http://php.net/is_readable"><methodname>is_readable()</methodname></ulink>.
            La fonction <acronym>PHP</acronym> ne recherche pas le fichier spécifié dans les répertoires de
            l'<code>include_path</code>, contrairement à
            <methodname>Zend_Loader::isReadable()</methodname>.
        </para>
    </sect2>

    <sect2 id="zend.loader.load.autoload">
        <title>Utiliser l'autoloader</title>

        <para>
            La classe Zend_Loader contient une méthode
            <methodname>Zend_Loader::autoload()</methodname> que vous pouvez inscrire dans le <acronym>PHP</acronym> SPL
            autoloader. Par commodité, <classname>Zend_Loader</classname> fournit la fonction
            <methodname>registerAutoload()</methodname> qui enregistre automatiquement sa méthode
            <methodname>autoload()</methodname>. Si l'extension <code>spl_autoload</code> n'est pas présente
            dans l'environnement <acronym>PHP</acronym>, alors la méthode <methodname>registerAutoload()</methodname> lèvera une
            <classname>Zend_Exception</classname>.
        </para>

        <example id="zend.loader.load.autoload.example">
            <title>Exemple d'inscription de la méthode de callback autoloader</title>

            <programlisting language="php"><![CDATA[
Zend_Loader::registerAutoload();
]]></programlisting>
        </example>

        <para>
            Après avoir inscrit le callback vers l'autoload de Zend Framework, vous pouvez
            appeler une classe de Zend Framework sans l'avoir explicitement chargé auparavant. La
            méthode autoload utilise automatiquement <methodname>Zend_Loader::loadClass()</methodname>
            quand vous appelez une classe.
        </para>

        <para>
            Si vous avez étendu la classe <classname>Zend_Loader</classname>, vous pouvez
            passer un argument optionnel à <methodname>registerAutoload()</methodname>, pour spécifier la classe
            de laquelle vous souhaitez enregistrer la méthode <methodname>autoload()</methodname>.
        </para>

        <example id="zend.loader.load.autoload.example-extended">
            <title>Exemple d'inscription de la méthode de callback autoloader d'une classe
            étendue</title>

            <para>
                A cause de la sémantique de référencement des fonctions statiques en <acronym>PHP</acronym>, vous
                devez implémenter le code pour les méthodes <methodname>loadClass()</methodname> et
                <methodname>autoload()</methodname>, et la méthode <methodname>autoload()</methodname> doit appeler
                <methodname>self::loadClass()</methodname>. Si votre méthode <methodname>autoload()</methodname> délégue à
                son parent l'appel <methodname>self::loadClass()</methodname>, alors cela appellerait la méthode
                de même nom dans la classe parente et non dans la sous-classe.
            </para>

            <programlisting language="php"><![CDATA[
class Mon_Chargeur extends Zend_Loader
{
    public static function loadClass($class, $dirs = null)
    {
        parent::loadClass($class, $dirs);
    }

    public static function autoload($class)
    {
        try {
            self::loadClass($class);
            return $class;
        } catch (Exception $e) {
            return false;
        }
    }}

Zend_Loader::registerAutoload('Mon_Chargeur');
]]></programlisting>
        </example>

        <para>
            Vous pouvez effacer un callback d'autoload. <methodname>registerAutoload()</methodname> a un
            paramètre optionnel, qui est réglé à <constant>TRUE</constant> par défaut. S'il vaut
            <constant>FALSE</constant>, le callback de l'autoload est alors effacé de la pile des autoload
            SPL.
        </para>
    </sect2>
</sect1>