I want to add custom event handler to object's method.
I've got a class with method.
class Post {
public function Add($title) {
// beforeAdd event should be called here
echo 'Post "' . $title . '" added.';
return;
}
}
I want to add an event to method Add
and pass method's argument(s) to the event handler.
function AddEventHandler($event, $handler){
// What should this function do?
}
$handler = function($title){
return strtoupper($title);
}
AddEventHandler('beforeAdd', $handler);
Is it possible to do something like this? Hope my question is clear.
Should be pretty easy using the functions defined here http://www.php.net/manual/en/book.funchand.php
In particular you should keep an handler array (or array of arrays if you want multiple handlers for the same event) and then just do something like
function AddEventHandler($event, $handler){
$handlerArray[$event] = $handler;
}
or
function AddEventHandler($event, $handler){
$handlerArray[$event][] = $handler;
}
in case of multiple handlers.
Invoking the handlers then would be just matter of calling "call_user_func" (eventually in a cycle if multiple handlers are needed)
Well, if you are using < php 5.3 then you cannot create a closure in such a way, but you can come close with create_function(); This would be
$handler = create_function('$title', 'return strtoupper($title);');
Then you store $handler in the class and you can call it as you desire.
You have multiple methods how to do it described by ircmaxell here.
And here is ToroHook used in ToroPHP (Routing lib).
class ToroHook {
private static $instance;
private $hooks = array();
private function __construct() {}
private function __clone() {}
public static function add($hook_name, $fn){
$instance = self::get_instance();
$instance->hooks[$hook_name][] = $fn;
}
public static function fire($hook_name, $params = null){
$instance = self::get_instance();
if (isset($instance->hooks[$hook_name])) {
foreach ($instance->hooks[$hook_name] as $fn) {
call_user_func_array($fn, array(&$params));
}
}
}
public static function remove($hook_name){
$instance = self::get_instance();
unset($instance->hooks[$hook_name]);
var_dump($instance->hooks);
}
public static function get_instance(){
if (empty(self::$instance)) {
self::$instance = new Hook();
}
return self::$instance;
}
}
It is simple call it like this:
ToroHook::add('404', function($errorpage){
render("page/not_found", array("errorpage" => $errorpage));
});
Take look on my sphido/events library:
on('event', function () {
echo "wow it's works yeah!";
});
fire('event'); // print wow it's works yeah!
add_filter('price', function($price) {
return (int)$price . ' USD';
});
echo filter('price', 100); // print 100 USD
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With