Я пытаюсь использовать автозагрузку в 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; } ?>