6

Drupal が使用するものと非常によく似たフック システムを構築する方法を見つけようとしています。Drupal では、特定の方法で関数に名前を付けるだけで、モジュールが有効になっている場合にフックとして自動的に呼び出されます。

ここで Stackoverflow の他の回答を見てきましたが、このタイプの機能を PHP アプリケーションに組み込む方法について実際に回答しているものはありません。

4

4 に答える 4

8

これが drupal が行う方法であり、それを行う方法です。命名規則による文字列連結の使用。function_exists() と call_user_func_array() を使用すると、すべて設定する必要があります。

トリックを行う 2 つの内部 drupal 関数を次に示します (module.inc)。

function module_invoke() {
     $args = func_get_args();
     $module = $args[0];
     $hook = $args[1];
     unset($args[0], $args[1]);
     $function = $module .'_'. $hook;
     if (module_hook($module, $hook)) {
     return call_user_func_array($function, $args);
  }
}

function module_hook($module, $hook) {
    return function_exists($module .'_'. $hook);
}

したがって、呼び出すだけで済みます

module_invoke('ModuleName','HookName', $arg1, $arg2, $arg3);

最終的に呼び出す

ModuleName_HookName($arg1,$arg2,$arg3);
于 2012-09-19T00:03:12.473 に答える
3

PHP を使用get_defined_functionsして関数名の文字列の配列を取得し、定義済みの形式でそれらの名前をフィルター処理することができます。

PHP ドキュメントからのこのサンプル:

<?php
function myrow($id, $data)
{
    return "<tr><th>$id</th><td>$data</td></tr>\n";
}

$arr = get_defined_functions();

print_r($arr);
?>

次のような出力が得られます。

Array
(
    [internal] => Array
        (
            [0] => zend_version
            [1] => func_num_args
            [2] => func_get_arg
            [3] => func_get_args
            [4] => strlen
            [5] => strcmp
            [6] => strncmp
            ...
            [750] => bcscale
            [751] => bccomp
        )

    [user] => Array
        (
            [0] => myrow
        )

)

より明示的なフック システムと比較すると、これは大ざっぱな手法ですが、機能します。

于 2012-09-18T23:52:12.787 に答える
2

私は Drupal の内部構造に詳しくありませんが、おそらく Reflection を使用してそれを行っています。

http://php.net/manual/en/book.reflection.php

フック関数を含む PHP ページを含め、リフレクションを使用して特定の命名規則に一致する関数またはクラス メソッドを見つけ、関数ポインタを保存して、必要に応じてそれらの関数を呼び出します (モジュールのライフサイクルのイベントなど)。

于 2012-09-18T23:52:03.063 に答える
0

なぜ存在する関数を使用しないのですか? 開発者は特定の方法で関数に名前を付けることができ、フックコードは関数が存在することを確認して呼び出すだけです

于 2012-09-19T00:11:09.503 に答える