8

次を使用して登録されたオートローダーがありますspl_autoload_register()

class MyAutoLoader{
   public function __construct(){
       spl_autoload_register(array($this, 'loader'));
   }

   public function loader($className){
       var_dump($className);
   }
}

$al = new MyAutoLoader(); //Register the autoloader

から、var_dump()オートローダは多くのもの、データベースに挿入されるデータ、パラメータ化された SQL クエリなどで呼び出されるようです。

string 'name' (length=4)

string 'a:2:{s:5:"label";s:4:"Name";s:8:"required";b:1;}' (length=48)

string 'en_US' (length=5)

string 'object' (length=6)

string 'name = ?' (length=8)

これらのものはクラスになることはないため、やなどを使用してロードしnewないclass_exists()でください。

オートローダーはどのような状況/関数呼び出しで呼び出されますか? クラスではない「classNames」のオートロードが呼び出されるのを止めたいと思います。それぞれ$classNameが を使用してチェックされ、file_exist()これらのデータ文字列をチェックするのはかなり非効率的だからです。


問題が解決しました。まず、Brad の提案に従ってバック トレースを実行し、トレースをファイルにダンプしました (ファイルを開いて追加する小さなスニペットを追加するだけです)。

明らかに、トレースは非常に大きかったのですが、見つけた中で最も単純なものを選びました。ちなみに、そのトレースはたまたま、すばらしいRedBean ORM ライブラリをラップするために私が作成したデータベース (ORM) ラッパーを呼び出したものでした。$classNameこれらの文字列はデータベースに出入りするデータであるため、me ダンプの結果もそれを検証します。

そうは言っても__call()、データベースラッパーへのメソッドをインターセプトし、何らかの処理を行い、それを RedBean に渡し、結果を処理してから、呼び出し元に送り返す があります。

問題: 処理中にis_subclass_of()instanceofを呼び出していますが、これは明らかにオートローダーにクラスのロードを試みるように要求します (ロードされたクラスがなくname =?、存在しないため)。

object解決策は、呼び出す前にis_subclass_of()and instanceof:があることを実際に確認することでしたif(is_object($someproperty) && is_subclass_of($someproperty))

$somepropertyがオブジェクトでない場合、すぐifに短絡してinstanceofandis_subclass_of()が呼び出されることはありません。これは、オートローダーへの呼び出しが行われないことを意味します。

ブラッドが述べたように、あらゆる種類のものをオートローダーに使用して含めるrequire_onceことは、大きなセキュリティリスクになる可能性があり、同時に、ファイルシステムを何度も使用することfile_exists()も非常に非効率的です.

したがって、結論として、オートローダは、他のクラス型関数、クラス存在関数、およびリフレクション メソッドを使用するinstanceofたびis_subclass_ofに呼び出されます。

したがって、この話の教訓は、混合型の変数に対してクラス型関数、または上記の関数のいずれかを使用する予定がある場合は、クラス型関数に渡す前にまずそれを確認することです。

4

2 に答える 2

3

オートローダーはどのような状況/関数呼び出しで呼び出されますか?

コメントに記載されている問題を考えると、これは基本的に二次的な質問になってしまったことを認識していますが、それでも答える価値があります。

__autoload()コード内の関数または によって登録されたコールバックであるオートロード関数は、spl_autoload_registerPHP が定義されていないクラスにアクセスする必要がある場合にのみ呼び出されます。これは、PHP にオートローダーを呼び出さないように指示する引数を持つなどのいくつかの例外を除いて、どこでも行われます。class_exists

PHP のマニュアルには、オートローディング専用のページがあります。違和感があれば見直すことをお勧めします。

于 2012-12-20T05:07:18.130 に答える
0

debug_backtraceまたはを使用debug_print_backtraceして、オートローダー関数が呼び出されている場所を正確に見つけることができます。

技術的には、スクリプトが存在しないクラス名を参照する場合にのみ、PHPによって呼び出される必要があります。

于 2012-12-20T04:16:58.787 に答える