30

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

それはすべてうまくいくようですが、私はこれが実際に許容できる実践と見なされていることを再確認したかっただけです。

4

6 に答える 6

32

確かに、よさそうだ。あなたがするかもしれない唯一のことは、彼らがヒットする可能性が最も高い順序でそれらを登録することです。たとえば、最も一般的に使用されるクラスがサービス、次にvos、次にプリンターである場合、現在の順序は完璧です。これは、それらが順番にキューに入れられて呼び出されるためです。これを行うと、パフォーマンスがわずかに向上します。

于 2010-09-14T15:53:50.157 に答える
19

あなたが使用することができます:

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

spl_autoload_register引数なしで使用spl_autoloadすると、のディレクトリでクラス名を検索するレジスタが登録されますinclude path。これにより、ファイルシステムでクラス名を探す前にクラス名が小文字になることに注意してください。

于 2010-09-14T16:04:04.573 に答える
4

大丈夫ですが、これらが特定のフォルダの下のフォルダである場合、たとえば

/library
    /JonoB
        /services
        /vos
        /printers

これらをクラス名に追加することを検討することをお勧めします。

JonoB_Services_Foo, JonoB_Vos_Bar, JonoB_Printers_Baz

次に、をアンダースコアで分割し、$classname各部分をフォルダ名として使用します。これは、 PEARクラス名の規則に似ています。このようにすると、ローダーは1つだけになります。

PEARコンベンションスタイルのクラス名の代わりに、名前空間自動ロードの例)を使用することもできますが、これらには共有ホスティングでまだ広く利用できないPHP5.3が必要であることに注意してください。また、アプリケーションはPHP <5.3との下位互換性がありません(それが問題になる場合)。

于 2010-09-14T15:48:37.880 に答える
3

他のすべての答えからの良いアドバイス。

各オートローダーは、渡されるクラスを気にするかどうかを最初にチェックし、気にしない場合はすぐに戻る必要があることを付け加えておきます。

したがって、Gordonが提案するように実行し、各クラスにプレフィックスを追加する場合Services_Foo、オートローダーautoload_services()は「Services_」がの最初のサブストリングである$class_nameかどうかを確認し、そうでない場合はすぐにfalseを返して、以降の処理、特にファイルシステムチェックを節約します。

于 2010-09-14T16:01:46.293 に答える
2

もし私がそうすることになっていたなら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');    
于 2014-04-10T14:22:55.733 に答える
0

spl_autoload_registerを使用して独自のClassLoaderを作成しました。
利点は、関数が現在のフォルダーから始まるすべてのサブフォルダーを検索することです。
私はこのファイルをすべての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;
}
?>
于 2017-12-23T22:23:53.337 に答える