この記事では、PHP でのフック メカニズムの実装方法を主に紹介します。フック メカニズムの原理と実装プロセスを詳しく紹介します。興味がある人は詳しく学ぶことができます。 「フック」の概念 最近、PHP フレームワークでプロジェクトを拡張するためにこのメカニズムが使用されているのを見たので見てみましょう。
いわゆるフックメカニズムは、Windows プログラミングでよく使われるテクノロジです。主なアイデアは、関数を追加できる場所に事前にフックを埋め込むことです。このフックには実際的な意味はなく、この場所のロジックを再変更または追加する必要がある場合は、拡張されたクラスまたはメソッドをマウントするだけです。ここまで。
プロジェクトコード内で、拡張する必要があると思われる場所(まだ拡張されていない)にフック関数を配置し、拡張する必要がある場合は、実装する必要のあるクラスや関数をマウントするこのフック上で、拡張を行うことができます。
オンラインでの実装例を見てみましょう。
プラグイン メカニズム全体には 3 つの部分が含まれています:1.hook プラグイン マネージャー クラス: これはコア ファイルであり、アプリケーションのグローバル Global オブジェクトです。これには 3 つの主な役割があります
1> 登録されているすべてのプラグインを監視し、これらのプラグイン オブジェクトをインスタンス化します。
2>すべてのプラグインを登録します。
3>フック条件が満たされると、対応するオブジェクトメソッドがトリガーされます。
2. プラグイン関数の実装: これは主にサードパーティの開発者によって行われますが、このルールはプラグインのメカニズムによって規定されており、プラグインによって異なります。仕組み的には。
3. プラグインのトリガー: つまり、フックのトリガー条件。これは、このフックをトリガーするためにプラグインを呼び出す必要がある場所に配置される小さなコードです。
----------------------------------他の人の解決策を見てください ------- -- ----------------------
1 つ目はプラグイン マネージャー クラス PluginManager です。このクラスはグローバル参照に配置し、すべてのアプリケーションで使用する必要があります。プラグインの場所、優先読み込みを使用する必要があります。
<?php /** * * 插件机制的实现核心类 */ class PluginManager { /** * 监听已注册的插件 * * @access private * @var array */ private $_listeners = array(); /** * 构造函数 * * @access public * @return void */ public function __construct() { #这里$plugin数组包含我们获取已经由用户激活的插件信息 #为演示方便,我们假定$plugin中至少包含 #$plugin = array( # 'name' => '插件名称', # 'directory'=>'插件安装目录' #); $plugins = get_active_plugins();#这个函数请自行实现 if($plugins) { foreach($plugins as $plugin) {//假定每个插件文件夹中包含一个actions.php文件,它是插件的具体实现 if (@file_exists(STPATH .'plugins/'.$plugin['directory'].'/actions.php')) { include_once(STPATH .'plugins/'.$plugin['directory'].'/actions.php'); $class = $plugin['name'].'_actions'; if (class_exists($class)) { //初始化所有插件 new $class($this); } } } } #此处做些日志记录方面的东西 } /** * 注册需要监听的插件方法(钩子) * * @param string $hook * @param object $reference * @param string $method */ function register($hook, &$reference, $method) { //获取插件要实现的方法 $key = get_class($reference).'->'.$method; //将插件的引用连同方法push进监听数组中 $this->_listeners[$hook][$key] = array(&$reference, $method); #此处做些日志记录方面的东西 } /** * 触发一个钩子 * * @param string $hook 钩子的名称 * @param mixed $data 钩子的入参 * @return mixed */ function trigger($hook, $data='') { $result = ''; //查看要实现的钩子,是否在监听数组之中 if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0) { // 循环调用开始 foreach ($this->_listeners[$hook] as $listener) { // 取出插件对象的引用和方法 $class =& $listener[0]; $method = $listener[1]; if(method_exists($class,$method)) { // 动态调用插件的方法 $result .= $class->$method($data); } } } #此处做些日志记录方面的东西 return $result; } }
次のステップは、単純なプラグインである DEMO_actions の実装です。シンプルな文章を出力するHello Worldプラグインです。実際の状況では、say_hello にはデータベースまたはその他の特定のロジックに対する操作が含まれる場合があります。
<?php /** * 这是一个Hello World简单插件的实现 */ /** *需要注意的几个默认规则: * 1. 本插件类的文件名必须是action * 2. 插件类的名称必须是{插件名_actions} */ class DEMO_actions { //解析函数的参数是pluginManager的引用 function __construct(&$pluginManager) { //注册这个插件 //第一个参数是钩子的名称 //第二个参数是pluginManager的引用 //第三个是插件所执行的方法 $pluginManager->register('demo', $this, 'say_hello'); } function say_hello() { echo 'Hello World'; } }
次のステップは、プラグイン呼び出しがトリガーされる場所です。たとえば、say_hello をブログのホームページ Index.php に配置したい場合は、index.php のどこかに次のように記述します。
$pluginManager->trigger('demo','');最初のパラメータはフックの名前を表し、2 番目のパラメータはプラグインの対応するメソッドのエントリパラメータです。この例では入力パラメータがないため、空です。 このような例は、基本的に「フック」プラグイン機構の実装方法とロジックを明確に表現しています。 関連する推奨事項:
フレームワーク Thinkphp5 単純な実装動作 フック
PHP で書かれた Webhook は git を実行できない
以上がPHPでフック機構を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。