# 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 ('.').

## 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.