我试图找出一种方法来构建一个非常类似于 Drupal 使用的钩子系统。使用 Drupal,您可以简单地以某种方式命名一个函数,如果启用该模块,它将自动作为钩子调用。
我在 Stackoverflow 上查看了其他答案,但没有一个真正给出如何将这种类型的功能构建到 PHP 应用程序中的答案。
我试图找出一种方法来构建一个非常类似于 Drupal 使用的钩子系统。使用 Drupal,您可以简单地以某种方式命名一个函数,如果启用该模块,它将自动作为钩子调用。
我在 Stackoverflow 上查看了其他答案,但没有一个真正给出如何将这种类型的功能构建到 PHP 应用程序中的答案。
这就是drupal 的工作方式,以及您可以做到的方式。使用带有名称约定的字符串连接。使用 function_exists() 和 call_user_func_array() 你应该已经准备好了。
这里有两个内部的 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);
您可以使用 PHPget_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
)
)
与更明确的钩子系统相比,这是一种粗略的技术,但它确实有效。
我不熟悉 Drupal 内部,但它可能使用反射来完成它:
http://php.net/manual/en/book.reflection.php
您将包含包含挂钩函数的 PHP 页面,然后使用反射来查找与特定命名约定匹配的函数或类方法,然后保存函数指针以在适当的时候调用这些函数(例如模块生命周期中的事件)。
为什么不只使用函数存在?开发人员可以以某种方式命名函数,钩子代码只是检查它是否存在然后调用它们