6

我试图找出一种方法来构建一个非常类似于 Drupal 使用的钩子系统。使用 Drupal,您可以简单地以某种方式命名一个函数,如果启用该模块,它将自动作为钩子调用。

我在 Stackoverflow 上查看了其他答案,但没有一个真正给出如何将这种类型的功能构建到 PHP 应用程序中的答案。

4

4 回答 4

8

这就是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);
于 2012-09-19T00:03:12.473 回答
3

您可以使用 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
        )

)

与更明确的钩子系统相比,这是一种粗略的技术,但它确实有效。

于 2012-09-18T23:52:12.787 回答
2

我不熟悉 Drupal 内部,但它可能使用反射来完成它:

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

您将包含包含挂钩函数的 PHP 页面,然后使用反射来查找与特定命名约定匹配的函数或类方法,然后保存函数指针以在适当的时候调用这些函数(例如模块生命周期中的事件)。

于 2012-09-18T23:52:03.063 回答
0

为什么不只使用函数存在?开发人员可以以某种方式命名函数,钩子代码只是检查它是否存在然后调用它们

于 2012-09-19T00:11:09.503 回答