Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I build a simple php hook system that works like this?

Tags:

php

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.

like image 429
Shane Grant Avatar asked Sep 18 '12 23:09

Shane Grant


2 Answers

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);
like image 110
nachinius Avatar answered Oct 28 '22 08:10

nachinius


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.

like image 3
Matchu Avatar answered Oct 28 '22 08:10

Matchu