Pregunta

Como la mayoría de los desarrolladores web en estos días, estoy completamente disfrutando de los beneficios de la arquitectura MVC sólida para aplicaciones web y sitios. Al hacer MVC con PHP, carga automática, obviamente, viene en muy práctico.

Me he convertido en un fan de spl_autoload_register más simple definición de una sola función __autoload(), ya que esto es obviamente más flexible si estás incorporando diferentes módulos base que cada utilizar su propia carga automática. Sin embargo, nunca he sentido bueno de las funciones de carga que escribo. Implican una gran cantidad de cheques cuerda y la exploración de directorios con el fin de buscar posibles clases de cargar.

Por ejemplo, digamos que tengo una aplicación que tiene una ruta de la base definida como PATH_APP, y una estructura sencilla con directorios llamados models, views y controllers. A menudo emplear una estructura de nombres mediante el cual se nombran los archivos IndexView.php y IndexController.php dentro del directorio apropiado y modelos generalmente tienen ningún esquema particular de forma predeterminada. Puede que tenga una función de cargador para esta estructura como esta que consigue registrado en spl_autoload_register:

public function MVCLoader($class)
{
    if (file_exists(PATH_APP.'/models/'.$class.'.php')) {
        require_once(PATH_APP.'/models/'.$class.'.php');
        return true;
    }
    else if (strpos($class,'View') !== false) {
        if (file_exists(PATH_APP.'/views/'.$class.'.php')) {
            require_once(PATH_APP.'/views/'.$class.'.php');
            return true;
        }
    }
    else if (strpos($class,'Controller') !== false) {
        if (file_exists(PATH_APP.'/controllers/'.$class.'.php')) {
            require_once(PATH_APP.'/controllers/'.$class.'.php');
            return true;
        }
    }
    return false;
}

Si no se encuentra después de eso, podría tener otra función para escanear subdirectorios en el directorio de modelos. Sin embargo, todo el if / else-ción, la comprobación de cuerda y la exploración de directorios parece ineficaz para mí, y me gustaría mejorarlo.

Estoy muy curioso lo que los nombres de archivo y las estrategias de carga automática otros desarrolladores podrían emplear. Estoy buscando específicamente para las buenas técnicas a emplear para la carga automática eficiente, y no alternativas a la carga automática.

¿Fue útil?

Solución

Esto es lo que he estado usando en todos mis proyectos (levantado directamente de la fuente de la última):

public static function loadClass($class)
{
    $files = array(
        $class . '.php',
        str_replace('_', '/', $class) . '.php',
    );
    foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $base_path)
    {
        foreach ($files as $file)
        {
            $path = "$base_path/$file";
            if (file_exists($path) && is_readable($path))
            {
                include_once $path;
                return;
            }
        }
    }
}

Si busco SomeClass_SeperatedWith_Underscores buscará SomeClass_SeperatedWith_Underscores.php seguido por SomeClass / SeperatedWith / Underscores.php raíz en cada directorio de la actual ruta de inclusión.

EDIT: Sólo quería poner por ahí que lo uso para la eficiencia en el desarrollo, y no necesariamente el tiempo de procesamiento. Si tiene PEAR en su camino a continuación, con ello sólo puede utilizar las clases y no tiene que incluirlos cuando los necesite.

tiendo a mantener mis clases en una jerarquía de directorios, con guiones rompiendo espacios de nombres ... Este código permite a mantener la estructura de archivos agradable y ordenado si quiero, o para inyectar un archivo de clase rápida y sin directorios anidados si desee (por la adición de una sola clase o dos para una biblioteca que es acusado, pero no forma parte del proyecto actualmente estoy trabajando en.)

Otros consejos

Aterricé en esta solución:

He creado un script único que atraviesa mi carpeta de biblioteca de clases (que contiene subcarpetas para los módulos / sistemas separados), y analiza el contenido del archivo en busca de definiciones de clases. Si encuentra una definición de clase en un archivo PHP (patrón de expresión muy simple), se crea un enlace simbólico:

class_name.php -> actual/source/file.php

Esto me permite usar una única función, carga automática simple que necesita sólo el nombre de la clase y de la ruta de la carpeta principal enlace simbólico, y no tiene que hacer ningún tipo de manipulación ruta / cadena.

La mejor parte es que puedo reorganizar mi código fuente completo o agregar un nuevo subsistema y basta con ejecutar la secuencia de comandos de generación de enlace de tener todo autocargado.

Si quieres eficiencia, entonces no debe utilizar la función de carga automática en absoluto. La función de carga automática es para ser perezoso. Usted debe proporcionar una ruta explícita a sus archivos de inclusión si se las incluye. Si su función de carga automática puede encontrar estos archivos entonces se podría codificar para encontrar explícitamente. Cuando se trabaja en la vista parte del código y el punto de cargar una nueva clase de vista, al permitir que la función de carga automática manejarlo, primero se supone que su clase es una clase de modelo? Eso es ineficiente. En lugar de ello su código sólo debe ser:

include_once $this->views_path . $class . '.php';

Si necesita varias rutas de acceso "Ver", hacer una función que carga puntos de vista:

public function load_view($class) {
    // perhaps there's a mapping here instead....
    foreach ($this->views_paths as $path) {
        $filename = $path . $class . '.php';
        if (file_exists($filename)) {
            include_once $filename;
        }
    }
    throw ....
}

En cualquier caso, en el punto donde se produce el include, usted tiene la información más grande / más precisa acerca de la clase que desea cargar. Gracias a esta información para cargar la clase completo es la única estrategia eficiente la carga de clases. Sí, usted puede terminar con más variables de clase o (Dios no lo quiera) algunas variables globales. Pero eso es un compromiso mejor que acaba de ser perezosos y partes de escaneo del sistema de archivos para su clase.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top