3

スクリプトで __autoload を使用して、必要に応じてクラスを含めています。私のスクリプトは、クラス名の手がかりを使用して、それを含むファイルを見つけます。モデルで終わる場合、それはモデル ディレクトリにあり、コントローラーはコントローラー ディレクトリにあるなどです。インターフェイスの実装を開始しているので、オートローダーを調整する必要があります。

理想的には、オブジェクトが作成されると、オートローダがオブジェクトのファイル名と格納場所を決定し、そのファイルを含めます。次に、実装するインターフェイスについてそのクラスに問い合わせ、それらのファイルを自動的に含めます。

何かのようなもの

function __autoload($classname){
    echo $classname;
    include ("classes/$classname.php");
    $interfaces = class_implements($classname,FALSE);
    foreach($interfaces as $name){
        if(!class_exists($name,FALSE)){
        include("interfaces/".$name."inter.php");
        }
    }
}

私がそうするときを除いて、エラーが発生します

11 行目の W:\xampp\htdocs\test\auto.php で __autoload() (以前は W:\xampp\htdocs\test\auto.php:5 で宣言されていた) を再宣言できません

__autoload() でこれを行うことはできませんか? オブジェクトのタイプとそれらが格納されている場所を区別するために、命名規則に頼り続ける必要がありますか?

4

3 に答える 3

6

実装されたインターフェイスが定義される前に、クラスを定義することはできません。追加の未知のインターフェイスは、オートロード機能もトリガーします。これは、3 行目でクラスをインクルードすると、インターフェースとして.autoload 関数が再び$classnameトリガーされることを意味します。2 番目の呼び出しから戻ると、__autoload()もう一度インターフェイスを含めようとしますが、「既に定義されている」ために失敗します。

追加: using__autoload()は using に対して非推奨ですspl_autoload_register()

于 2011-08-25T18:11:27.730 に答える
4

追加のオートロード関数を登録するには、 spl_autoload_registerを使用します。指定する autoload 関数はコールバックです。つまり、メソッドまたはクラス メソッドを渡すことができます。そうすれば、名前の競合を心配することなく、さまざまなクラスに追加のオートロードを追加できます。

[編集]

このようには機能しません。KingCrunch の賢明な回答をご覧ください。

これがうまくいくとしても、私はそれをしないようにアドバイスします. オートロード関数を 1 つにするか、使用するライブラリやフレームワークごとにオートロード関数を追加することで、オートロードを単純明快に保つことができます。関数を追加すると、デバッグが非常に複雑になる場合があります。

于 2011-08-25T18:05:34.320 に答える
2

すでにクラスの命名規則に依存しているため、既存の __autoload を変更してインターフェイス名も解析します。すべてのインターフェースに「I_something」という名前を付ければ、簡単に変更できます。

命名規則に依存したくない場合は、ある種のクラスおよびインターフェース レジストリをセットアップする必要があります。レジストリは、次のようなハードコードされた配列と同じくらい単純にすることができます。

function __autoload($classname) {
    $classlist=array('MyClass1','path/to/file/myclass1.php',
                          'MyClass2','path/to/file/foo.php',
...
                         );

    $interfacelist=array('MyInterface1','path/to/file/bar1.php',
                              'I_foo','path/to/file/bibble.php',
...
                         );
            $path=$classname;
            if(array_key_exists($classname,$classlist)) {
                $path=PATH_CLASSES.$classlist[$classname];
            } else if(array_key_exists($classname,$interfacelist)) {
                $path=PATH_INTERFACES.$interfacelist[$classname];
            }
            if(file_exists($path)) {
                require_once($path);
            } else {
                $e=new Exception("Problem with path: $path");
            }
}
于 2011-08-25T18:12:36.443 に答える