Support Forums

Full Version: Simple PHP Hooking
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Yet another tutorial that I previously wrote.

--

For those of us that love dynamic content, but not all the messy code that is required for it, hooks is my favorite way to go. An example of a hook class looks something like:
PHP Code:
<?php
    
class Hooks {
        public function 
add($hook,$class=null,$method=null,$args=null) {
            if (empty(
$method)) die("You must include a method (function) when defining add_hook.");
            
$this->hooks[$hook][]=array((!empty($class)?array($class,$method):$method),$args);
            return 
$this;
        }
        public function 
clear($hook=null) { if (!empty($hook)) unset($this->hooks[$hook]); else $this->hooks=null; }
        public function 
run($hook) {
            if (empty(
$this->hooks[$hook])) return $this;
            foreach (
$this->hooks[$hook] as $hkey=>$hvalue) {
                if (
is_array($hvalue[0])) $hvalue[0]=array($hvalue[0][0],$hvalue[0][1]);
                if (!empty(
$hvalue[1])) if (!is_array($hvalue[1])) call_user_func($hvalue[0],$hvalue[1]); else call_user_func_array($hvalue[0],$hvalue[1]);
                else 
call_user_func($hvalue[0]);
            }
            return 
$this;
        }
    }
?>

To add a hook in your PHP file, you would do something like this:
PHP Code:
<?php
    $hooks 
= new Hooks;

    
// For a function:
    
function doTitle() { echo $current->title; }
    
$hooks->add('head_title',null,'doTitle');

    
// For a class:
    
class Output {
        function 
body_final() { echo implode("\n",$this->body); }
    }
    
$hooks->add('page_body','Output','body_final');

    
// To pass multiple arguments into a function, you must use:
    
function test($arg1,$arg2) { echo "Arg1: {$arg1}, Arg2: {$arg2}"; }
    
$hooks->add('page_body',null,'test',array('test','ing'));
?>

Then in your index file, you can run something like the following:
PHP Code:
<?php
    
// You must include the hook file here, or you can make an includes file to do all of your startup (as is normally done).
    
include 'hooks.php';
    include 
'yourscript.php';
?><!DOCTYPE html>
<html>
    <head>
        <?php $hooks->run('head_meta'); ?>
        <title><?php $hooks->run('head_title'); ?></title>
        <?php
            $hooks
->run('head_links');
            
$hooks->run('head_scripts');
        
?>
    </head>
    <body>
        <?php $hooks->run('page_body'); ?>
    </body>
</html> 

Do not forget that if you plan on running a hook more than once, you will need to clear the hook after you run it before adding more functions to run. Otherwise you're going to have the functions you previously used, plus the functions that you have input since you ran the hook last.

There are many, many, more ways to do this. Some more extravagant than others. This is just a small example of what can be done, with very few lines of code.
PHP and it's endless powers.... Big Grin
I see you are not passing by reference in Hook::add(), you should try it out. IMO, it is better if you pass the instance of an object to the function instead of creating a new instance within it.
"&$hook"
PHP Code:
public function add(&$hook,$class=null,$method=null,$args=null

btw... The syntax may scare some people ;)
Keep up the good work...
$hook isn't meant to be referenced. $hook is the name of the hook that you will use in run($hook) to execute the hooks that are defined with that name.