Skip to content

Instantly share code, notes, and snippets.

@will0
Created March 12, 2013 16:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save will0/5144211 to your computer and use it in GitHub Desktop.
Save will0/5144211 to your computer and use it in GitHub Desktop.
PHP Functions with "hooks" to add before, after, and around actions/fixers/filters/exception handlers/listeners/whatevers
<?php
/**
* MegaMethods
* ===========
*
* They do stuff, on steroids
**/
namespace MM;
class Trampoline {
private $hooks, $impl, $next;
public function __construct(&$hooks, $impl) {
$this->hooks =& $hooks;
$this->impl = $impl;
$this->next = count($hooks);
}
public function __invoke() {
$args = func_get_args();
if($this->next--) {
$hook = $this->hooks[$this->next];
$args[] = $this;
return call_user_func_array($hook, $args);
} else {
return call_user_func_array($this->impl, $args);
}
}
}
class MegaMethod {
private $impl, $hooks;
public function __construct($impl) {
$this->impl = $impl;
$this->hooks = array();
}
public function __invoke() {
$tramp = new Trampoline($this->hooks, $this->impl);
return call_user_func_array($tramp, func_get_args());
}
public function add_hook($hookfn) {
$this->hooks[] = $hookfn;
}
}
$classify = new MegaMethod(function($num) {
return (string) $num;
});
// optional, this is really handy for making the calls look more "normal" and eliminating "global $foo" all over
function classify($num) {
global $classify;
return $classify($num);
}
foreach(array(3 => "Fizz", 5 => "Buzz", 15 => "FizzBuzz") as $mod => $replace) {
$classify->add_hook(function($num, $chain) use($mod, $replace) {
return ($num % $mod) ? $chain($num) : $replace;
});
}
foreach(range(1,15) as $num) {
$class = classify($num);
echo "$class\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment