CI フレームワークを使用すると、システムのコア コードを変更せずに、システムのコア機能 (キャッシュの書き換え、出力など) を追加または変更できます。たとえば、システムでフックが有効になっている場合 (config.php で $config['enable_hooks'] = TRUE;)、特定のフックを追加すると、システムは特定の時間に特定のスクリプトをトリガーできます。
$hook['post_system'] = array( 'class' => 'frameLog', 'function' => 'postLog', 'filename' => 'post_system.php', 'filepath' => 'hooks',);
ログイン後にコピー
上記のフック A post_system フックが定義されており、最終ページのレンダリング後のスクリプト処理に使用されます (パラメーターの意味は後ほどまたはマニュアルで参照でき、ここではこれ以上の説明は行いません)。
それでは質問です:
- フックとは何ですか?
- CI でサポートされているフックは何ですか?
- CI ではフックはどのように実装されますか?
段階的に見てみましょう。
1. フックとは何ですか?
Baidu 百科事典でのフックの定義は次のとおりです:
フックは実際にはメッセージを処理するプログラム セグメントであり、システム コールを通じてシステムにフックされます。特定のメッセージが送信されるたびに、フック プログラムは宛先ウィンドウに到達する前にメッセージをキャプチャします。つまり、フック関数が最初に制御を取得します。このとき、フック関数はメッセージを処理(変更)したり、処理せずにメッセージの配信を継続したり、メッセージの配信を強制的に終了したりすることができます。
上記の定義からいくつかの点がわかります:
- フックはイベント駆動型モデルであり、そのコアは当然のことながらイベントです (CI の pre_system や pre_controller などはすべて特定のイベントです)。
- イベント駆動型であるため、次の 2 つの最も重要な手順を含める必要があります: (1) イベントの登録。フックの場合はフックフックの取り付けを指します。 (2). イベントトリガー。特定の時点で特定のフックを呼び出し、対応するフック プログラムを実行します。
- イベント駆動型であるため、統一されたフック ポイントを持つ複数の登録イベントもサポートする必要があります。
- フックを開始した後、プログラムの流れが変化する可能性があり、適切に処理しないとフックが相互に呼び出す可能性があります。同時に、フックを有効にするとプログラムがある程度複雑になり、デバッグが困難になります。
2. CI の事前定義フック
CI は、次の 7 つの利用可能なプリセット フック ポイントを提供します:
pre_system: システム読み込みの初期段階のフックを指します
pre_controller: コントローラーを呼び出します。 、ルーティングとセキュリティのチェックが完了しました
Post_controller_constructor: コントローラーがインスタンス化された後、メソッド呼び出し前
Post_controller: コントローラーが完全に実行された後
Display_override: ディスプレイを書き換えます
キャッシュオーバーライド:キャッシュを書き換えます
Post_system: 最終ページがクライアントに送信された後
3. CI のフックの実装
CI のフックのコア機能は、Hook コンポーネントによって完了します。コンポーネント画像:
その内:
enabled: フック機能が有効かどうかを示すフラグ。
hooks: システムで有効になっているフックのリストを保存します
in_progress: このフラグはフック間の相互呼び出しによって引き起こされる無限ループを防ぐために使用されることが後でわかります。
_construct は Hook コンポーネントのコンストラクターで、_initialize が呼び出されて初期化作業が完了します
_call_hook: _run_hook を呼び出して、指定されたフック プログラムを呼び出します。 CodeIgniter.php で、_call_hook が実際に外部呼び出しに提供されるインターフェイスであることを以前に見てきました。
_run_hook: フックプログラムを実際に実行する関数
始める前に、事前定義されたフックの構造を投稿しましょう。この構造はソース コード全体に現れる可能性があるため、この構造のパラメータの意味を知る必要があります。
$hook['xx'] = array( 'class' => 'xx', //钩子调用的类名,可以为空 'function' => 'xx',//钩子调用的函数名 'filename' => 'xx',//该钩子的文件名 'filepath' => 'xx',//钩子的目录 'params' => 'xx'//传递给钩子的参数);
ログイン後にコピー
ログイン後にコピー
1).フックコンポーネントの初期化
_initialize 関数はフックコンポーネントを初期化するために使用されます: この関数の主なタスクは次のとおりです:
(1) 設定ファイルでフック関数が有効になっているかどうかを確認します。ロードする必要があるConfig (構成管理コンポーネント):
1 2 3 4 5 6 | $CFG =&load_class( '構成' 、 'core'); (2) 定義されたフック リストをロードします 同様に、異なるフックを有効にするために異なる ENVIRONMENT を設定することもできます:
1 2 3 4 5 6 7 8 |
if (define( 'ENVIRONMENT' ) AND is_file (APPPATH . 'config/' '/hooks.php ' )) {sinclus(apppath。 'config/' .environment。 '/hooks.php'); include (APPPATH. 'config/hooks.php' ); } (3) フックチェック。フックが設定されていない場合、または設定されたフックの形式が間違っている場合は、処理は行われず、直接終了します。 if ( ! isset( $ook ) OR ! is_array ( $hook )) | { return ; }
初期化後、Hook::フックは定義されたフックリストを保存します: 指定されたフックを呼び出す _call_hook はメインプログラム内で直接呼び出されるインターフェースです。このインターフェースの主なタスクは次のとおりです: | (1) フックが有効かどうか、および呼び出しフックが事前定義されているかどうかを確認します (有効になっていない場合、または呼び出しフックが存在しない場合は、直接戻ります)。
1 2 3 4 | if ( ! $this ->enabled OR ! isset( $this ->hooks[ $this ])) { FALSE を返します。 (2)。同じフック ポイントに対して複数のフックが有効になっているかどうかを確認します。有効な場合は、
1 2 3 4 5 6 7 | if (isset( $this ->hooks[ $that ][0]) AND is_array ( $this ->hooks[ $that ][0])) {
それ以外の場合、
(3)。フックは1つだけです。それを実行するのは1つだけです。 $this ->_run_hook( $this -> ;hooks[ $that ]); | _run_hook は実際にフックを実行する関数です。 3. Run は特定のフック プログラムを実行します _run_hook 関数は、事前定義されたフック配列をパラメータとして受け取り、次のように実装されます:
(1)。単に配列ではない (当然、有効なフックではない) 場合は、直接返します:
1 2 3 | 4
if ( ! is_array ( $data ) ) { return FALSE; | (2). フックの実行ステータスを確認します。 in_progress は、現在のフックの実行ステータスをマークするために使用されます。このパラメータの主な機能は、フック間の相互呼び出しによって引き起こされる無限ループを防ぐことです。 1 2
3
4 if ( $this ->in_progress == TRUE) { | }
(3). Hook的合法性检查。 为了方便讲述,我们再次提出一个预定义的hook需要的参数:
$hook['xx'] = array( 'class' => 'xx', //钩子调用的类名,可以为空 'function' => 'xx',//钩子调用的函数名 'filename' => 'xx',//该钩子的文件名 'filepath' => 'xx',//钩子的目录 'params' => 'xx'//传递给钩子的参数); ログイン後にコピー ログイン後にコピー 其中class和params是可选参数,其他3个参数为必选参数,如果不提供,则由于无法准确定位到hook程序,只能直接返回:
1 2 3 4 5 6 7 8 9 10 11 |
if ( ! isset( $data [ 'filepath' ]) OR ! isset( $data [ 'filename' ])) { return FALSE; } $filepath = APPPATH. $data [ 'filepath' ]. '/' . $data [ 'filename' ]; if ( ! file_exists ( $filepath )) { return FALSE; } | (4). この時点で、フック プログラムの場所は次の 2 つの状況で確認されています。 a 事前定義されたフックのクラス パラメーターが空であり、手続き型呼び出しメソッドが使用されていることを示します。次に、フック ファイル内の関数 xxx を直接実行します b. クラス パラメータは空ではなく、実際のフック プログラムは $class->$function です。関数パラメータが設定されていない場合、フックは実行できず、直接戻ります:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | $class = FALSE;
$function = FALSE; $params = ''; if (isset( $data [ 'クラス' ]) AND $data [ 'class' ] != '' ) { $class = $data [ 'class' ] } /* フック関数の取得 */ if ( isset( $ data [ 'function' ])) { $function = $data [ 'function' ] } /* 渡されたフックパラメータを取得*/ if (isset( $ data [ ' params' ])) { $params = $data [ 'params' ]; } /* クラスも関数も存在しない場合、フック プログラムは見つからず、直接返されます * / if ( $class === FALSE AND $function === FALSE) { return FALSE } (5)。上記の 2 つのケースで実行フラグ in_progress を設定し、フックを実行します。 5
6
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* 指向性オブジェクトの設定方法 } $ HOOK = new $class; $HOOK -> $function ( $params ) } /* 手続き型実行モード*/ else | {
if ( ! function_exists( $function ) ) { require ( $filepath ) } $function ( $params ); 最後に忘れずに設定してくださいin_progress フラグは false で、成功した実行フラグを返します: 1 2 $this ->in_progress = FALSE; return TRUE; ; フックコンポーネントの完全なソースコード: 参考資料 1. http://codeigniter.org.cn/user_guide/general/hooks.html マニュアル | 2. //itopic.org/codeigniter-hook.html 3. http://codeigniter.org.cn/forums/thread-4947-1-1.html フック実装のレイアウト |
|
|