I am trying to figure out a way to build a hook system very similar to the one that Drupal uses. With Drupal you can simply name a function a certain way and it will automatically be invoked as a hook if the module is enabled.
I have looked at the other answers here on Stackoverflow, but none of them really give an answer of how to build this type of feature into a PHP application.
This is how drupal does it, and how you can do it. Using string concatenation with name convention. With function_exists() and call_user_func_array() you should be all set.
Here are the two internal drupal functions that make the trick (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);
}
Therefore, you only need to invoke
module_invoke('ModuleName','HookName', $arg1, $arg2, $arg3);
which will finally call
ModuleName_HookName($arg1,$arg2,$arg3);
You could use PHP's get_defined_functions
to get an array of strings of function names, then filter those names by some predefined format.
This sample from the PHP docs:
<?php
function myrow($id, $data)
{
return "<tr><th>$id</th><td>$data</td></tr>\n";
}
$arr = get_defined_functions();
print_r($arr);
?>
Outputs something like this:
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
)
)
It's kinda a sketchy technique when compared to a more explicit hook system, but it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With