# Cargando archivos y clases dinámicamente

La clase `Zend_Loader` incluye métodos para ayudar a cargar archivos dinámicamente.

## Zend_Loader vs. require_once()

Los métodos de `Zend_Loader` 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 `Zend_Loader` sobre el uso de funciones tradicionales de PHP como `require_once()` .

## Cargando Archivos

El método estático `Zend_Loader::loadFile()` carga un archivo PHP . El archivo cargado puede contener cualquier código PHP . El método se comporta como un envoltorio para la función PHP `include()` . Este método devuelve un booleano `FALSE` en caso de fallo, por ejemplo, si el archivo especificado no existe.

### Ejemplo del Método loadFile()

    Zend_Loader::loadFile($filename, $dirs=null, $once=false);

El argumento `$filename` 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 `$filename` . El archivo `$filename` sólo puede contener caracteres alfanuméricos, guiones ("-"), barras bajas ("_"), o puntos ("."). No hay ninguna restricción en el argumento `$dirs` .

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

El argumento `$once` es un booleano. Si es `TRUE` , `Zend_Loader::loadFile()` esa la función PHP `include_once()` para cargar el archivo, de lo contrario se utiliza la función PHP `include()` .

## Cargando Clases

El método estático `Zend_Loader::loadClass($class, $dirs)` carga un archivo PHP y comprueba la existencia de la clase.

### Ejemplo del método loadClass()

    Zend_Loader::loadClass('Container_Tree',
        array(
            '/home/production/mylib',
            '/home/production/myapp'
        )
    );

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.

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

Si el archivo no es encontrado o la clase no existe después de la carga, `Zend_Loader::loadClass()` lanza una `Zend_Exception` .

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

### Loading Classes from PHP Namespaces

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 PHP Framework Interop Group PSR-0 reference implementation.

Under this guideline, the following rules apply:

- Each namespace separator is converted to a `DIRECTORY_SEPARATOR` when loading from the file system.

- Each "_" character in the CLASS NAME is converted to a `DIRECTORY_SEPARATOR`. The "_" character has no special meaning in the namespace.

- The fully-qualified namespace and class is suffixed with ".php" when loading from the file system.

As examples:

- `\Doctrine\Common\IsolatedClassLoader` => `/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php`

- `\namespace\package\Class_Name` => `/path/to/project/lib/vendor/namespace/package/Class/Name.php`

- `\namespace\package_name\Class_Name` => `/path/to/project/lib/vendor/namespace/package_name/Class/Name.php`

## Comprobando si un Archivo Puede Ser Leído

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

### Ejemplo del método isReadable()

    if (Zend_Loader::isReadable($filename)) {
        // hace algo con $filename
    }

El argumento `$filename` especifica el nombre de archivo que comprobar. Puede contener información de la ruta. Este método envuelve la función PHP `is_readable()` . La función PHP no busca en `include_path` , mientras que `Zend_Loader::isReadable()` sí.

## Usando el Autoloader

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

### Ejemplo de registro del método callback del autoloader

    Zend_Loader::registerAutoload();

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 `autoload()` usa automáticamente `Zend_Loader::loadClass()` cuando referencie una clase.

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

### Ejemplo de registro del método de callback autoload desde una clase extendida

Debido a la semántica de referencia de funciones estáticas en PHP , se debe implementar código tanto para la clase `loadClass()` como `autoload()` , y `autoload()` debe llamar a `self::loadClass()` . Si su método `autoload()` delega en su padre la llamada a `self::loadClass()` , entonces llamará al método con ese nombre en la clase padre, no la subclase.

    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');

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