PHP でオートロードを実装するには 2 つの方法があります:
1.インターセプター__autoload()
2. グローバル変数関数ポインター autoload_func を指定された関数に設定します。通常、C 拡張機能で使用されます
本質的に、前者は後者によって達成されます。
解析プロセス、PHP5.3.6ソースコード
=>Zend/zend_vm_def.h 1894 行目
ZEND_VM_HANDLER(109,ZEND_FETCH_CLASS,...
)=>zend_execute_API.c 1526 行目
zend_class_entry *zend_fetch_class(const char *class_name,...
=>zend_execute_API.c 1564 行目
if(zend_lookup_class_ex(クラス名,クラス名_len,...
=>zend_execute_API.c 1039 行目
ZEND_API int zend_lookup_class_ex(const char *na...
=>zend_execute_API.c 1121 行目
retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
=>zend_execute_API.c 758 行目
zend_call_function
名前が示すように、zend_call_function の主な機能は PHP 関数を呼び出すことです。そのパラメータ fcall_info と fcall_cache は、それぞれ zend_fcall_info と zend_fcall_info_cache という 2 つの重要な構造体を指します
zend_call_function の主なワークフローは次のとおりです:
fcall_cache.function_handler が NULL でない場合、fcall_cache.function_handler が指す関数が直接実行されます。
fcall_cache.function_handler が NULL の場合は、fcall_info.function_name という名前の関数を探し、存在する場合はそれを実行します。
をまとめると以下のようになります
オートロードメカニズムの主な実行プロセスは次のとおりです:
(1) executor グローバル変数関数ポインタ autoload_func が NULL かどうかを確認します。
(2) autoload_func が NULL でない場合、__autoload() 関数が定義されているかどうかを確認せずに、autoload_func ポインタが指す関数を直接実行してクラスをロードします。
(3) autoload_func が NULL の場合、システムに __autoload() 関数が定義されているかどうかを確認します。定義されていない場合は、エラーが報告されて終了します。__autoload() 関数が定義されている場合は、__autoload() が実行されてクラスのロードが試行され、ロード結果が返されます。
自動ロードにより、オブジェクト指向とコードの再利用が容易になりますが、複数のクラス ライブラリで異なる __autoload が使用されると混乱が生じる可能性があります。
これは、さまざまな開発者のインターセプター関数を自動ローディング関数のハッシュテーブルに登録する spl_autoload で解決できます。
spl が自動ローディングを実装するメカニズムは、自動ローディング機能を備えたさまざまな関数を格納するハッシュテーブルを維持することです。
自動ロードメカニズムがトリガーされると、zend はクラスが正常にロードされるか、ロードが失敗した後に戻るまで、このハッシュテーブル内の関数を走査して実行します。
オートロード関数を使用する必要がある場合は、関数 spl_autoload_register() または spl_autoload_register(autoloadfuncitonname) を使用します
パラメータを指定しない spl_autoload_register() は、デフォルトで spl_autoload() 関数をロードします。この関数は機能が制限されており、inlcude_path で指定された拡張子を持つクラス ライブラリのみを検索できます。
パラメータを含む spl_autoload_register() は、デフォルトでは spl_autoload() 関数をロードしなくなりました。
配列を返す spl_autoload_functions() を通じて、現在のオートロード ハッシュテーブル内の関数を表示できます
注: spl_autoload を使用する場合、spl_autoload_register(__autoload) を使用してハッシュテーブルに明示的に追加されない限り、システムはインターセプター __autoload を無視します
コード