<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 20243 -->
    <!-- Reviewed: no -->
<sect1 id="zend.loader.load">

    <title>Cargando archivos y clases dinámicamente</title>

    <para> La clase <classname>Zend_Loader</classname> incluye métodos para
        ayudar a cargar archivos dinámicamente. </para>

    <tip>
        <title>Zend_Loader vs. require_once()</title>
        <para> Los métodos de <classname>Zend_Loader</classname> tienen más
            utilidad si el nombre de archivo que necesita cargar es variable.
            Por ejemplo, si éste se basa en un parametro de entrada del usuario
            o argumento de un método. Si carga un archivo o clase cuyo nombre es
            constante, no hay ningún beneficio al usar
                <classname>Zend_Loader</classname> sobre el uso de funciones
            tradicionales de <acronym>PHP</acronym> como <ulink
                url="http://php.net/require_once">
                <methodname>require_once()</methodname>
            </ulink> . </para>
    </tip>

    <sect2 id="zend.loader.load.file">

        <title>Cargando Archivos</title>

        <para> El método estático
                <methodname>Zend_Loader::loadFile()</methodname> carga un
            archivo <acronym>PHP</acronym> . El archivo cargado puede contener
            cualquier código <acronym>PHP</acronym> . El método se comporta como
            un envoltorio para la función <acronym>PHP</acronym>
            <ulink url="http://php.net/include">
                <methodname>include()</methodname>
            </ulink> . Este método devuelve un booleano
                <constant>FALSE</constant> en caso de fallo, por ejemplo, si el
            archivo especificado no existe. </para>

        <example id="zend.loader.load.file.example">
            <title>Ejemplo del Método loadFile()</title>
            <programlisting language="php"><![CDATA[
Zend_Loader::loadFile($filename, $dirs=null, $once=false);
]]></programlisting>
        </example>

        <para> El argumento <varname>$filename</varname> especifica el archivo
            que se va a cargar, el cual no debe contener ninguna información de
            rutas. Una verificación de seguridad es efectuada sobre
                <varname>$filename</varname> . El archivo
                <varname>$filename</varname> sólo puede contener caracteres
            alfanuméricos, guiones ("-"), barras bajas ("_"), o puntos ("."). No
            hay ninguna restricción en el argumento <varname>$dirs</varname> . </para>

        <para> El parámetro <varname>$dirs</varname> especifica en qué carpetas
            buscar el archivo. Si el valor es <constant>NULL</constant> , sólo
            se buscará en el <methodname>include_path</methodname> ; si el valor
            es un string o un array, se buscará en la carpeta o carpetas
            especificadas , seguidas del <methodname>include_path</methodname> . </para>

        <para> El argumento <varname>$once</varname> es un booleano. Si es
                <constant>TRUE</constant> ,
                <methodname>Zend_Loader::loadFile()</methodname> esa la función
                <acronym>PHP</acronym>
            <ulink url="http://php.net/include">
                <methodname>include_once()</methodname>
            </ulink> para cargar el archivo, de lo contrario se utiliza la
            función <acronym>PHP</acronym>
            <ulink url="http://php.net/include_once">
                <methodname>include()</methodname>
            </ulink> . </para>

    </sect2>

    <sect2 id="zend.loader.load.class">

        <title>Cargando Clases</title>

        <para> El método estático <methodname>Zend_Loader::loadClass($class,
                $dirs)</methodname> carga un archivo <acronym>PHP</acronym> y
            comprueba la existencia de la clase. </para>

        <example id="zend.loader.load.class.example">
            <title>Ejemplo del método loadClass()</title>
            <programlisting language="php"><![CDATA[
Zend_Loader::loadClass('Container_Tree',
    array(
        '/home/production/mylib',
        '/home/production/myapp'
    )
);
]]></programlisting>
        </example>

        <para> La cadena que especifica la clase es convertida a una ruta
            relativa sustituyendo las barras bajas (_) por el separador de
            carpeta de su Sistema Operativo, y añadiendo '.php'. En el ejemplo
            de arriba, 'Container_Tree' se convierte en 'Container\\Tree.php' en
            Windows. </para>

        <para> Si <varname>$dirs</varname> es una cadena o un array,
                <methodname>Zend_Loader::loadClass()</methodname> busca las
            carpetas en el orden suministrado. El primer archivo encontrado es
            cargado. Si el archivo no existe en el <varname>$dirs</varname>
            especificado, entonces se busca en el
                <methodname>include_path</methodname> del entorno
                <acronym>PHP</acronym> . </para>

        <para> Si el archivo no es encontrado o la clase no existe después de la
            carga, <methodname>Zend_Loader::loadClass()</methodname> lanza una
                <classname>Zend_Exception</classname> . </para>

        <para>
            <methodname>Zend_Loader::loadFile()</methodname> se usa para cargar,
            así que el nombre de la clase puede contener únicamente caracteres
            alfanuméricos, guiones ('-'), barras bajas ('_'), y puntos ('.'). </para>

            <note>
            <title>Loading Classes from PHP Namespaces</title>

            <para>
                Starting in version 1.10.0, Zend Framework now allows loading classes from PHP
                namespaces. This support follows the same guidelines and implementation as that
                found in the <ulink
                    url="http://groups.google.com/group/php-standards/web/psr-0-final-proposal">PHP
                Framework Interop Group PSR-0</ulink> reference implementation.
            </para>

            <para>
                Under this guideline, the following rules apply:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        Each namespace separator is converted to a
                        <constant>DIRECTORY_SEPARATOR</constant> when loading from the file system.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        Each "_" character in the <emphasis>CLASS NAME</emphasis> is converted to a
                        <constant>DIRECTORY_SEPARATOR</constant>.  The "_" character has no special
                        meaning in the namespace.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        The fully-qualified namespace and class is suffixed with ".php" when loading
                        from the file system.
                    </para>
                </listitem>
            </itemizedlist>

            <para>
                As examples:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        <classname>\Doctrine\Common\IsolatedClassLoader</classname> =&gt;
                        <filename>/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php</filename>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <classname>\namespace\package\Class_Name</classname> =&gt;
                        <filename>/path/to/project/lib/vendor/namespace/package/Class/Name.php</filename>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <classname>\namespace\package_name\Class_Name</classname> =&gt;
                        <filename>/path/to/project/lib/vendor/namespace/package_name/Class/Name.php</filename>
                    </para>
                </listitem>
            </itemizedlist>
        </note>
    </sect2>

    <sect2 id="zend.loader.load.isreadable">

        <title>Comprobando si un Archivo Puede Ser Leído</title>

        <para> El método estático
                <methodname>Zend_Loader::isReadable($pathname)</methodname>
            devuelve <constant>TRUE</constant> si el archivo en la ruta
            $pathname existe y tiene permisos de lectura,
                <constant>FALSE</constant> en caso contrario. </para>

        <example id="zend.loader.load.isreadable.example">
            <title>Ejemplo del método isReadable()</title>
            <programlisting language="php"><![CDATA[
if (Zend_Loader::isReadable($filename)) {
    // hace algo con $filename
}
]]></programlisting>
        </example>

        <para> El argumento <varname>$filename</varname> especifica el nombre de
            archivo que comprobar. Puede contener información de la ruta. Este
            método envuelve la función <acronym>PHP</acronym>
            <ulink url="http://php.net/is_readable">
                <methodname>is_readable()</methodname>
            </ulink> . La función <acronym>PHP</acronym> no busca en
                <methodname>include_path</methodname> , mientras que
                <methodname>Zend_Loader::isReadable()</methodname> sí. </para>

    </sect2>

    <sect2 id="zend.loader.load.autoload">

        <title>Usando el Autoloader</title>

        <para> La clase <classname>Zend_Loader</classname> contiene un método
            que se puede registrar con <acronym>PHP</acronym> SPL autoloader.
                <methodname>Zend_Loader::autoload()</methodname> es el método
            callback. Por comodidad, <classname>Zend_Loader</classname> permite
            a la función <methodname>registerAutoload()</methodname> registrar
            su método <methodname>autoload()</methodname> . Si la extensión
                <methodname>spl_autoload</methodname> no está presente en el
            entorno <acronym>PHP</acronym> , entonces el método
                <methodname>registerAutoload()</methodname> lanza una
                <classname>Zend_Exception</classname> . </para>

        <example id="zend.loader.load.autoload.example">
            <title>Ejemplo de registro del método callback del
                autoloader</title>
            <programlisting language="php"><![CDATA[
Zend_Loader::registerAutoload();
]]></programlisting>
        </example>

        <para> Después de registrar el callback de autoload de Zend Framework,
            se pueden referenciar clases de Zend Framework sin tener que
            cargarlas explícitamente. El método
                <methodname>autoload()</methodname> usa automáticamente
                <methodname>Zend_Loader::loadClass()</methodname> cuando
            referencie una clase. </para>

        <para> Si ha extendido la clase <classname>Zend_Loader</classname> , se
            puede pasar un argumento opcional a
                <methodname>registerAutoload()</methodname> , para especificar
            la clase a partir de la cual registrar un método
                <methodname>autoload()</methodname> . </para>

        <example id="zend.loader.load.autoload.example-extended">
            <title>Ejemplo de registro del método de callback autoload desde una
                clase extendida</title>
            <para> Debido a la semántica de referencia de funciones estáticas en
                    <acronym>PHP</acronym> , se debe implementar código tanto
                para la clase <methodname>loadClass()</methodname> como
                    <methodname>autoload()</methodname> , y
                    <methodname>autoload()</methodname> debe llamar a
                    <methodname>self::loadClass()</methodname> . Si su método
                    <methodname>autoload()</methodname> delega en su padre la
                llamada a <methodname>self::loadClass()</methodname> , entonces
                llamará al método con ese nombre en la clase padre, no la
                subclase. </para>
            <programlisting language="php"><![CDATA[
class My_Loader 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('My_Loader');
]]></programlisting>
        </example>

        <para> Se puede eliminar un callback de autoload.
                <methodname>registerAutoload()</methodname> tiene un segundo
            parámetro opcional, que es <constant>TRUE</constant> por defecto. Si
            este parámetro es <constant>FALSE</constant> , el callback de
            autoload será borrado de la pila de autoload SPL. </para>

    </sect2>

</sect1>
