Friday, June 1, 2012

Best way to allow plugins for a PHP application


I am starting a new web application in PHP and this time around I want to create something that people can extend by using a plugin interface. How does one go about writing 'hooks' into their code so that plugins can attach to specific events?



Source: Tips4all

4 comments:

  1. You could use an Observer pattern. A simple functional way to accomplish this:

    <?php/** Plugin system **/$listeners = array();/* Create an entry point for plugins */function hook(){ global $listeners; $num_args = func_num_args(); $args = func_get_args(); if($num_args < 2) trigger_error("Insufficient arguments", E_USER_ERROR); // Hook name should always be first argument $hook_name = array_shift($args); if(!isset($listeners[$hook_name])) return; // No plugins have registered this hook foreach($listeners[$hook_name] as $func){ $args = $func($args); } return $args;}/* Attach a function to a hook */function add_listener($hook, $function_name){ global $listeners; $listeners[$hook][] = $function_name;}//////////////////////////** Sample Plugin **/add_listener('a_b', 'my_plugin_func1');add_listener('str', 'my_plugin_func2');function my_plugin_func1($args){ return array(4, 5);}function my_plugin_func2($args){ return str_replace('sample', 'CRAZY', $args[0]);}//////////////////////////** Sample Application **/$a = 1;$b = 2;list($a, $b) = hook('a_b', $a, $b);$str = "This is my sample application\n";$str .= "$a + $b = ".($a+$b)."\n";$str .= "$a * $b = ".($a*$b)."\n";$str = hook('str', $str);echo $str;?>

    Output:

    This is my CRAZY application4 + 5 = 94 * 5 = 20

    Notes:

    For this example source code, you must declare all your plugins before the actual source code that you want to be extendable. I've included an example of how to handle single or multiple values being passed to the plugin. The hardest part of this is writing the actual documentation which lists what arguments get passed to each hook.

    This is just one method of accomplishing a plugin system in PHP. There are better alternatives, I suggest you check out the WordPress Documentation for more information.

    Sorry, it appears underscore characters are replaced by HTML entities by Markdown? I can re-post this code when this bug gets fixed.

    Edit: Nevermind, it only appears that way when you are editing

    ReplyDelete
  2. The hook and listener method is the most commonly used, but there are other things you can do. Depending on the size of your app, and who your going to allow see the code (is this going to be a FOSS script, or something in house) will influence greatly how you want to allow plugins.

    kdeloach has a nice example, but his implementation and hook function is a little unsafe. I would ask for you to give more information of the nature of php app your writing, And how you see plugins fitting in.

    +1 to kdeloach from me.

    ReplyDelete
  3. Definitely check out Drupal's method. Here's some of their own documentation.
    They use a pretty nice model where the module's name is used as a prefix to all exposed functions. A lot of the mechanics are automatic that way.

    ReplyDelete
  4. Check:


    http://framework.zend.com/manual/de/zend.loader.html
    http://code.google.com/p/phpplexus/

    ReplyDelete