Share this question

Welcome to Teachnovice Q&A, where you can ask questions and receive answers from other members of the community.

This is a collaboratively edited question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Writing a Pluggable PHP Application – Part 1?

1 like 0 dislike
216 views

I take no credit for this. This was posted on failover by Jethro Solomon.

Of the many things that separate great PHP applications from the so-so ones is extensibility. Here, I will give you a quick introduction to coding hooks into your scripts. This will allow you or third parties to add functionality to your code without even touching it.

WTF is a hook?

Hooks allow you to call additional functions at specific times while your application is running. For example, a user may want to modify some content from you application before displaying it. We are going to create two types of hooks, action hooks and filter hooks (yes, similar to WordPress). Action hooks will allow you to call additional functions during a certain point in the main application, while filter hooks will enable you to parse variables before output via a custom function.

For the purpose of this tutorial, I am taking a procedural approach. I am going to show you basic concepts. I would advise that you put your own thought as to security and limiting what a user may do, before using the code.

Today we will cover action hooks…

Action Hooks – The Base Code

$action_events is an array which will hold all of the registered events and associated functions.

$action_events = array();

The function hook_action() accepts one argument, that, being the name of the event. This function is used by you.

function hook_action($event)
{
    global $action_events;
 
    if(isset($action_events[$event]))
    {
        foreach($action_events[$event] as $func)
        {
            if(!function_exists($func)) {
                die('Unknown function: '.$func);
            }
                call_user_func($func, $args);
            }
    } 
}

The function register_action() accepts two arguments; first, the name of the event and the second, the name of the function to be called. This function is used by, say, a plugin developer for your software.

function register_action($event, $func)
{
    global $action_events;
    $action_events[$event][] = $func;
}

Action Hooks – Putting them into action

Lets pretend we are developing a simple CMS. We want to provide a way for people do ‘do stuff’ when the content of a page is displayed. In this CMS, we have a function to display content. All we have to do is add a hook like so:

function show_content($content) {
    echo $content;
    hook_action('content_display');
}

Now, we can make a custom function that is executed after the content is displayed. The person in question is very new to your CMS, and wants to send an email every time the content is displayed. So, he writes his function and registers it:

function send_email() {
    mail('caffeinated@example.com', 'Page Viewed!', 'Doing this is really going to fill your inbox!');
}
 
register_action('content_display','send_email');

And it works!

Thank you for reading. Part two will expand on this idea by introducing filter hooks. Part three will wrap it all up into a neat directory structure and show you how to load plugins into a basic application. I’m holding out on a downloadable package until then ;-)

asked Oct 15, 2016 by pak786 (2,100 points)  
reopened Oct 24, 2016 by pak786

Well, i solved the problem by passing in the value as an argument into the call_user_func() ,,

Here is the second ver of the hook_action() function

function hook_action($event, $value = "")
{
  global $action_events, $current_event;
  $args = array();
  if(isset($action_events[$event]))
  {
    foreach($action_events[$event] as $func)
    {
      if(!function_exists($func)){
       die('Unknown function: '.$func);
      }
     $args[1] = $value;
     $value = call_user_func($func, $args);
    }
  }
  return $value;
}

Glad you found the solution, very similar to the hook_filter function in part 2. So if you want to keep separate ‘actions’ and ‘filters’, simply rename your new function hook_filter and keep the old one too. Thanks for stopping by!

I’ve noticed one huge flaw in your code

You’ve passed the variable $args to the call_user_func but you have not specified anyway to set $args, nor does it have a default value

Instead, you should call call_user_func_array($func, $args)

and then in the function declaration, do

function hook_action($event, array $args = array())

The array declaration forces you to supply an array in PHP 5

That way, each value in the $args array becomes a new argument for the function we’re calling. you can also pass through references by doing this

$args = array(&$somedata);
hook_action(‘onChange’, $args);

References would be good for recording errors into an array so you can deal with them better. e.g. a form validation system thats extendible with custom checks

Thanks for pointing that out, I will make changes accordingly (to all three posts :S ).

Your answer

Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.
Anti-spam verification:
To avoid this verification in future, please log in or register.
...