php spl_autoload_register
-
02-10-2019 - |
質問
私は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
アンダースコアで、各部品をフォルダー名として取得します。これはに似ています ナシのクラス名コンベンション. 。これにより、ローダーが1つしかありません。
梨のコンベンションスタイルのクラス名の代わりに、あなたも使用することができます 名前空間 (オートロードの例)、しかし、これらには共有ホスティングではまだ広く利用できないphp5.3が必要であることに注意してください。また、アプリケーションはPHP <5.3と後方互換性がありません(それが問題の場合)。
他のすべての答えからの良いアドバイス。
各オートローダーは、まずクラスが渡されるクラスを気にかけているかどうかを確認し、そうでない場合はすぐに戻ってくることを追加します。
Gordonが提案して各クラスにプレフィックスを追加するようにする場合、 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');
spl_autoload_registerを使用して自分のクラスローダーを書きました。
利点は、関数が現在のフォルダーから始まるすべてのサブフォルダーを見ることです。
このファイルをすべてのPHPファイルに含めるだけで、include/requiredディレクティブについて心配する必要はありません。
単に動作する:-)
<?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;
}
?>