2

オートローダーの登録方法と作成方法さえ理解していますが、それはまったく問題ありません。ただし、主な問題は次のようなもののために2つのオートローダーを並べて実行する方法です。

class project_one_folder_class extends project_two_folder_class{}

子クラスは、別のプロジェクトにある親クラスに連絡して呼び出しているプロジェクトに属していることに気付くでしょう。

プロジェクトがリンクされている方法プロジェクト2のクラスは常にオートローダーによって表示されますが、プロジェクト1のクラスは表示されません。

だから私がこれについて考えたのは、2つのオートローダーを書いてそれらを登録することでした。なぜなら、phpはもう一方を調べるからです。しかし、phpは一方だけを調べており、もう一方は調べていないようです。

これをどのように解決しますか?

編集

プロジェクト2は親、プロジェクト1は子です。これは、この質問に投稿されたものよりも拡張された質問です。

これをさらに拡張するのが私のクラスです。

class AisisCore_Loader_AutoLoader{

    protected static $_instance;

    public function get_instance(){
        if(null == self::$_instance){
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    public function reset_instance(){
        self::$_instance = null;
    }

    public function register_auto_loader(){
        spl_autoload_register(array($this, 'load_class'));
        spl_autoload_register(array($this, 'load_child_class'));
    }

    public function load_class($class){
        $path = str_replace('_', '/', $class);
        if(file_exists(get_template_directory() . '/' . $path . '.php')){
            require_once(get_template_directory() . '/' . $path . '.php');
        }
    }

    public function load_child_class($class){
        $path = str_replace('_', '/', $class);
        if(file_exists(get_stylesheet_directory() . '/' . $path . '.php')){
            require_once(get_stylesheet_directory() . '/' . $path . '.php');
        }
    }   
}

現在、このクラスは親プロジェクトのすべてをロードします。親プロジェクトオブジェクトを子プロジェクトにロードすることもできます。ただし、このクラスが見つからないため、このクラスを使用して子オブジェクトをロードすることはできません。

WordPressに精通している人はすぐに言うでしょう、そうですget_template_directory、あなたが望むときに持っているからです。これget_stylesheet_directoryを知っています-私は2つのオートローダーを書きたいと思いますget_stylesheet_directoryget_stylesheet_directory

class project_one_folder_class extends project_two_folder_class{}

エラーなしで動作し、ロードされます。

4

4 に答える 4

1

もちろん、最初のfile_existsがfalseを返したときに、まったく同じオートローダーで2番目のパスを検索することもできます。

2番目のパスに2番目のオートローダーを登録することもできます。

PHPドキュメントはこれに対処します:

複数の自動ロード機能が必要な場合は、これをspl_autoload_register()許可します。自動ロード機能のキューを効果的に作成し、定義された順序で各機能を実行します。対照的に、__autoload()定義できるのは1回だけです。

于 2013-03-20T21:02:21.977 に答える
1

これは少し大雑把ですが、実際には、複数のディレクトリ内をチェックするオートローダーが1つだけ必要です。

abstract class Hakre_Theme_AutoLoader
{
    public static $directories;

    public static function init()
    {
        // configure paths
        self::$directories = array(
            get_template_directory(), // current theme, parent in case of childtheme
            get_stylesheet_directory(), // current theme, child in case of childtheme
        );

        // please double check if you really need to prepend
        return spl_autoload_register('Hakre_Theme_AutoLoader::autoload', true, true);
    }

    public static function autoload($class)
    {
        $filename = str_replace('_', '/', $class) . '.php';

        foreach (self::$directories as $directory) {
            $path = $directory . '/' . $filename;
            if (is_file($path)) {
                require($path);
                return; # leave because the class has been loaded
            }
        }
    }
}


Hakre_Theme_AutoLoader::init();

## If you're unsure all worked out properly:
var_dump(Hakre_Theme_AutoLoader::$directories);

これは実際にそれを行うはずですが、私はそれをテストしていません。を参照してくださいvar_dump。正しいディレクトリが登録されているかどうかをデバッグできます。2つのディレクトリをチェックインするという理由だけで、複数のコールバックを持つ必要はありません。

于 2013-03-20T21:25:56.663 に答える
1

自動読み込みプロセスを分離してください!

PHPは次のよ​​うに機能しています。ある時点で、コードの実行は、まだロードされていないクラス参照に遭遇します。$obj = new project_one_folder_class()

これで、最初に追加されたものから始めて、登録されたオートローダー関数が呼び出されます(後で追加されたものが「prepend」パラメーターを使用している場合を除く)。

最初の(および後続のすべての)autoload関数は、ロードする必要のあるクラスの名前を取得します。関数には、決定するタスクがあります

  1. このクラスをロードするのはタスクですか?そうでない場合は、何もせず、他の関数にロードを試みさせます。
  2. この関数がクラスのロードを担当している場合は、既知のクラス名からパスとファイル名を作成し、このファイルを要求してください。

ステップ1は通常、ロードされるクラス名が特定のプレフィックスで始まるかどうかを調べることで解決されます。あなたの場合、「project_one_」で始まるクラスのロードを担当するオートローダーは、他の何かで始まる他のクラスをロードしようとすべきではありません。

ステップ2は、オートローダーがオートロードを実行する必要があることを認識している場合に実行されます。これで、クラス名が相対パスとファイル名に変換され、ベースディレクトリが追加されてから、ファイルが必要になります。

別のクラスを拡張する(またはインターフェイスを実装する)クラスを定義するファイルを要求すると、まだ不明なクラスで自動ロードの別の実行をトリガーできます。あなたの場合、自動ロードプロセスはクラス名「project_two_folder_class」で再開されます。「project_one_」クラスの最初のオートローダーは、この2番目のクラス名で再度呼び出されますが、これらのクラスのロード方法がわからないため、何も実行しないでください。これは、「project_two_」クラスを認識しているオートローダー次第です。

オートローダーが異なれば、登録の順序は重要ではありません。もしそうなら、オートローダーは誤動作します。

クラス名のアンダースコア文字と名前空間のバックスラッシュを単純に変換するのが一般的なパターンであるため、最後に「.php」を追加してから、定義されたベースディレクトリからこのファイルをロードしてみてください。これらのオートローダーのうちの2つは同一であり、問​​題は次の2つの場合に1つのオートロード関数のみを構成することになります。ファイルへの相対パスに変換されます。

ファイルが特定のディレクトリに存在するかどうかをすべての場合にチェックすることは、パフォーマンスにとって最適ではありません。クラス名を見るだけではロードできないことがわかるファイルに対して、多くのチェックを行うことになります。

ちなみに、オートローダー関数はシングルトンである必要はありません。実際、シングルトンの実装は壊れており、役に立たない。でオートローダーをインスタンスnew化し、コンストラクターにいくつかの構成値を渡して、を呼び出しspl_autoload_register()ます。これで完了です。

于 2013-03-21T01:22:00.697 に答える
0

複数のローダーを追加できます。各関数をspl_autoload_register()に登録するだけです。

手続き型:

spl_autoload_register('loader_function1'));
 // your second class location
spl_autoload_register('loader_function2'));

またはOOスタイルで

spl_autoload_register(array($this, 'loader_function1'));
spl_autoload_register(array($this, 'loader_function2'));

しかし、あなたの質問に基づいて:あなたはおそらくもっと柔軟なオートローダーにここの別の質問で私の答えを見てもらうことによって同じことを達成することができます: ワードプレスプラグインのクラスオートローダー

于 2017-08-24T13:05:07.550 に答える