Pregunta

Estoy tratando de tomar ventaja de auto carga en PHP. Tengo varias clases en diferentes directorios, y por eso he bootstrap la carga automática de la siguiente manera:

function autoload_services($class_name)
{
    $file = 'services/' . $class_name. '.php';
    if (file_exists($file))
    {
        require_once($file);
    }
}

function autoload_vos($class_name)
{
    $file = 'vos/' . $class_name. '.php';
    if (file_exists($file))
    {
        require_once($file);
    }
}

function autoload_printers($class_name)
{
    $file = 'printers' . $class_name. '.php';
    if (file_exists($file))
    {
        require_once($file);
    }
}

spl_autoload_register('autoload_services');
spl_autoload_register('autoload_vos');
spl_autoload_register('autoload_printers');

Todo parece bien el trabajo, pero yo sólo quería volver a comprobar que este hecho se considera una práctica aceptable.

¿Fue útil?

Solución

Por supuesto, se ve bien. La única cosa que puede hacer es registrarlos en el orden en que es más probable que golpear. Por ejemplo, si sus clases que se utilizan con mayor frecuencia están en servicios, entonces vos, a continuación, impresoras, el orden que se tiene es perfecto. Esto se debe a que están en cola y llamados en orden, por lo que va a lograr un rendimiento ligeramente mejor al hacer esto.

Otros consejos

Se puede usar:

set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './services', './vos', './printers')));
spl_autoload_register();

spl_autoload_register sin argumentos registrarán spl_autoload que buscará el nombre de clase en los directorios de la include path . Tenga en cuenta que esto va en minúsculas el nombre de clase antes de buscar en el sistema de archivos.

Está bien, pero si estos son sólo las carpetas por debajo de una determinada carpeta, por ejemplo.

/library
    /JonoB
        /services
        /vos
        /printers

es posible que desee considerar la adición de éstos a sus nombres de las clases, por ejemplo.

JonoB_Services_Foo, JonoB_Vos_Bar, JonoB_Printers_Baz

y luego dividir el $classname por el guión bajo y tomar cada parte como nombre de la carpeta. Esto es similar a PERA nombre de la clase de convenciones . De esta manera sólo tendría un cargador.

En lugar de PEAR nombres de las clases de estilo de convenciones, también se puede utilizar espacios de nombres ( carga automática ejemplo ), pero ser conscientes de que éstos requieren PHP5.3 que no está ampliamente disponible en alojamiento compartido todavía. Y su aplicación no será compatible con PHP <5.3 a continuación (si eso es un problema).

Un buen consejo de todas las otras respuestas.

Permítanme añadir que cada cargador automático debe comprobar primero si es que se preocupa por la clase que se pasa en, y volver de inmediato si no.

Así que si haces lo que Gordon sugiere y añadir un prefijo a cada clase, a continuación, para Services_Foo la autoload_services() cargador automático debe ver si "SERVICIOS_" es la primera subcadena de $class_name, y si no return false inmediatamente a ahorrar en ningún otro proceso, cheques especialmente sistema de archivos.

Si se suponía que refactor your code , sería

function custom_autoload($class_name){
        $dirs = array('services','vos','printers') 
        foreach($dirs as $dir){ 
            $file = $dir.'/'.$class_name. '.php';
            if (file_exists($file)){
               require $file;
               break; // if i have maintained naming conventions as per dir as there
                  // is no point for looking eg: sample1_printer.php in the vos/ 
                 // or printer/. this way iam avoiding unnecessary loop
             }
        }
 }
    spl_autoload_register('custom_autoload');    

He escrito mi propio cargador de clases usando spl_autoload_register.
La ventaja es que las miradas de función en cada subcarpeta a partir de la carpeta actual.
Me basta con incluir este archivo en todos los archivos PHP y no tener que preocuparse acerca de cualquier include / requieren Directiva.
Simplemente funciona: -)

<?php
spl_autoload_register('AutoLoadClasses');

/************************************************************************************
 * AutoLoadClasses
 *
 * Diese Funktion lädt Klassen in gleichnamigen Dateien bei Bedarf automatisch nach,
 * sobald eine (bis dahin unbekannte) Klasse erstmalig instanziert wird.
 * $var = new MeineKlasse; => Es wird nach der Datei class_MeineKlasse.php gesucht
 * Die Suche erfolgt rekursiv in allen Unterordnern ausgehend von dem Ordner, in dem
 * das aufrufende PHP-Script liegt.
 *
 * Michael Hutter / Dezember 2017
 */
function AutoLoadClasses($Klassenname, $StartOrdner = null)
{
    if (is_null($StartOrdner))
    {
        $StartOrdner = __DIR__; # Ausgangspunkt für die Suche: Ordner, in dem sich das aufrufende PHP-Script befindet
        $StartInstanz = true;
    }
    $ZielDateiname = "class_$Klassenname.php";
    $FileList = scandir($StartOrdner, 1); # Sortierung 1 => kommt schneller zum Ziel, falls Ordnernamen im allgemeinen mit einem Großbuchstaben beginnen
    foreach ($FileList as $file) # Alle Dateien und Ordner durchgehen
    {
        $Vollpfad = $StartOrdner.DIRECTORY_SEPARATOR.$file;
        if (is_dir($Vollpfad) && (substr($file, 0, 1) !== '.')) # Ordner?
        {
            #echo "Ordner $StartOrdner<br>";
            $result = AutoLoadClasses($Klassenname, $Vollpfad);
            if ($result) return; # Abbruch, falls Ziel gefunden
        }
        else if (preg_match('/\.php$/i' , $file)) # .php-Datei?
        {
            #echo "$file<br>";
            if ($file == $ZielDateiname) # Dateiname entspricht Klassenname?
            {
                include $Vollpfad;
                return true; # Abbruch aller Rekursionen, da Ziel gefunden
            }
        }
    }
    if (isset($StartInstanz))
        die("<table border bgcolor=red><tr><td>Fehler: Die Datei <b>$ZielDateiname</b> konnte in keinem der Unterordner gefunden werden!</td></tr></table>");
    return false;
}
?>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top