PHP spl_autoload_register

Я пытаюсь использовать автозагрузку в PHP. У меня разные классы в разных каталогах, поэтому я загрузил автозагрузку следующим образом:

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

Кажется, все работает нормально, но я просто хотел дважды проверить, что это действительно считается приемлемой практикой.

Конечно, выглядит хорошо. Единственное, что вы можете сделать, это зарегистрировать их в том порядке, в котором они, скорее всего, попадут. Например, если ваши наиболее часто используемые классы находятся в сервисах, тогда vos, а затем принтеры, ваш заказ отлично. Это связано с тем, что они поставлены в очередь и называются в порядке, поэтому вы достигнете немного лучшей производительности, выполнив это.

Вы можете использовать:

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

Использование spl_autoload_register без аргументов будет регистрировать spl_autoload который будет искать имя класса в каталогах include path . Обратите внимание, что это приведет к изменению имени класса перед его поиском в файловой системе.

Все в порядке, но если это только папки под определенной папкой, например

 /library /JonoB /services /vos /printers 

вы можете захотеть добавить их в свои имена классов, например

 JonoB_Services_Foo, JonoB_Vos_Bar, JonoB_Printers_Baz 

а затем разделите $classname на $classname подчеркивания и возьмите каждую часть в качестве имени папки. Это похоже на соглашение с именем класса PEAR . Таким образом, у вас будет только один загрузчик.

Вместо названий классов стиля PEAR вы также можете использовать пространства имен ( пример автозагрузки ), но имейте в виду, что для них требуется PHP5.3, который пока не широко доступен на общедоступном хостинге. И ваше приложение не будет обратно совместимо с PHP <5.3, тогда (если это проблема).

Хороший совет из всех других ответов.

Позвольте мне добавить, что каждый автозагрузчик должен сначала проверить, не заботится ли он о сдаваемом классе, и немедленно вернуться, если нет.

Поэтому, если вы сделаете так, как предлагает Гордон, и добавьте префикс для каждого класса, то для Services_Foo автозагрузчик autoload_services() должен увидеть, является ли «Services_» первой подстрокой $class_name и если не возвращает false немедленно, чтобы сохранить дальнейшую обработку, особенно проверки файловой системы.

Если бы я должен был refactor your code , это было бы

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

Я написал собственный ClassLoader, используя spl_autoload_register.
Преимущество заключается в том, что функция просматривается в каждой подпапке, начиная с текущей папки.
Я просто включаю этот файл в каждый файл PHP и никогда не должен беспокоиться о директиве include / require.
Он просто работает 🙂

 <?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; } ?>