How to do a PHP hook system?
Asked Answered
T

3

16

How do you impliment a hook system in a PHP application to change the code before or after it executes. How would the basic architecture of a hookloader class be for a PHP CMS (or even a simple application). How then could this be extended into a full plugins/modules loader?

(Also, are there any books or tutorials on a CMS hook system?)

Therron answered 1/12, 2011 at 3:47 Comment(3)
possible duplicate of How does plugin system work (wordpress, mybb ...)?Seeker
This doesn't answer your question - but an alternative... Make template objects at the beginning of your script, load up the different objects throughout the execution by passing them around with the controller or initiating them with a template factory (i use it in the controller). Then, compile the templates into how you want them to look at the end. You can point to custom style sheets then too.Enrichment
Can you provide your own insights for this question? It's been a while since you asked this question and I'm interested to know what are the most important aspects you learned from your own experience with writing a custom CMSJer
N
31

You can build an events system as simple or complex as you want it.

/**
 * Attach (or remove) multiple callbacks to an event and trigger those callbacks when that event is called.
 *
 * @param string $event name
 * @param mixed $value the optional value to pass to each callback
 * @param mixed $callback the method or function to call - FALSE to remove all callbacks for event
 */
function event($event, $value = NULL, $callback = NULL)
{
    static $events;

    // Adding or removing a callback?
    if($callback !== NULL)
    {
        if($callback)
        {
            $events[$event][] = $callback;
        }
        else
        {
            unset($events[$event]);
        }
    }
    elseif(isset($events[$event])) // Fire a callback
    {
        foreach($events[$event] as $function)
        {
            $value = call_user_func($function, $value);
        }
        return $value;
    }
}

Add an event

event('filter_text', NULL, function($text) { return htmlspecialchars($text); });
// add more as needed
event('filter_text', NULL, function($text) { return nl2br($text); });
// OR like this
//event('filter_text', NULL, 'nl2br');

Then call it like this

$text = event('filter_text', $_POST['text']);

Or remove all callbacks for that event like this

event('filter_text', null, false);
Northeast answered 1/12, 2011 at 4:17 Comment(1)
its so simple.. and very effectiveDoldrums
B
2

Here's another solution:

Creating a hook

Run this wherever you want to create a hook:

x_do_action('header_scripts');


Attach a function to the hook

Then attach a function to the above by doing:

x_add_action('header_scripts','my_function_attach_header_scripts');

function my_function_attach_header_scripts($values) {

   /* add my scripts here */

}

Global variable to store all hooks/events

Add this to the top of your main PHP functions file, or equivalent

$x_events = array();
global $x_events;

Base functions

function x_do_action($hook, $value = NULL) {
    global $x_events;

    if (isset($x_events[$hook])) {

        foreach($x_events[$hook] as $function) {

            if (function_exists($function)) { call_user_func($function, $value); }

        }
    }

}

function x_add_action($hook, $func, $val = NULL) {
    global $x_events;
    $x_events[$hook][] = $func;

}
Bask answered 5/1, 2019 at 17:52 Comment(0)
M
0

this solutions has some problems that you can't set several function for one callable hook. you can fallow this code.



 $action = [];

 function apply($hook, $args){
    global $action;
    $action[$hook]['args'] = $args;
    return doa($hook, $args);
 }

 function add($hook, $func){
    global $action;
    $action[$hook]['funcs'][] = $func;
 }

 function doa($hook,$args){
    global $action;
    if(isset($action[$hook]['funcs'])){
        foreach($action[$hook]['funcs'] as $k => $func){
            call_user_func_array($func, $args);
       }
    }
    
 }

 add('this_is', 'addOne');
function addOne($user){
    echo "this is test add one $user <br>";
}
add('this_is', function(){
    echo 'this is test add two <br>';
});


add('this_is_2', 'addTwo');
function addTwo($user, $name){
    echo $user . '   ' . $name . '<br>';
}


function test(){
    echo 'hello one <br>';
    apply('this_is', ['user'=> 123]);
}


function test2(){
    echo 'hello two <br>';
    apply('this_is_2', ['user'=> 123, 'name' => 'mohammad']);
}
test();
test2();



Memo answered 7/10, 2020 at 7:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.