php实现hook函数
PHP实现Hook函数的方法
Hook(钩子)是一种在特定事件发生时插入自定义代码的机制。PHP可以通过多种方式实现Hook功能,以下是几种常见方法:
使用函数和变量钩子
通过维护一个全局的钩子数组,在特定位置调用注册的函数:
$hooks = [];
function add_hook($hook_name, $callback) {
global $hooks;
$hooks[$hook_name][] = $callback;
}
function do_hook($hook_name, ...$args) {
global $hooks;
if (isset($hooks[$hook_name])) {
foreach ($hooks[$hook_name] as $callback) {
call_user_func_array($callback, $args);
}
}
}
使用示例:
add_hook('before_save', function($data) {
echo "Before save: ".$data."\n";
});
do_hook('before_save', 'test data');
面向对象实现
使用类来封装Hook功能,更符合现代PHP开发规范:
class HookManager {
private static $hooks = [];
public static function add($name, $callback) {
self::$hooks[$name][] = $callback;
}
public static function run($name, ...$args) {
if (isset(self::$hooks[$name])) {
foreach (self::$hooks[$name] as $callback) {
call_user_func_array($callback, $args);
}
}
}
}
WordPress风格的Hook实现
参考WordPress的add_action和do_action实现:
function add_action($tag, $function_to_add, $priority = 10) {
global $wp_actions;
$wp_actions[$tag][$priority][] = $function_to_add;
}
function do_action($tag, ...$arg) {
global $wp_actions;
if (isset($wp_actions[$tag])) {
ksort($wp_actions[$tag]);
foreach ($wp_actions[$tag] as $priority => $functions) {
foreach ($functions as $function) {
call_user_func_array($function, $arg);
}
}
}
}
使用SplPriorityQueue实现优先级
如果需要带优先级的Hook系统:
class HookPriority {
private $hooks;
public function __construct() {
$this->hooks = new SplPriorityQueue();
}
public function add($callback, $priority = 0) {
$this->hooks->insert($callback, $priority);
}
public function run(...$args) {
foreach (clone $this->hooks as $callback) {
call_user_func_array($callback, $args);
}
}
}
实际应用示例
在MVC框架中实现前置和后置Hook:
class Controller {
protected $beforeAction = [];
protected $afterAction = [];
public function beforeAction($method, $callback) {
$this->beforeAction[$method][] = $callback;
}
public function afterAction($method, $callback) {
$this->afterAction[$method][] = $callback;
}
protected function runAction($method) {
// 执行前置Hook
if (isset($this->beforeAction[$method])) {
foreach ($this->beforeAction[$method] as $callback) {
call_user_func($callback);
}
}
// 执行主方法
$this->$method();
// 执行后置Hook
if (isset($this->afterAction[$method])) {
foreach ($this->afterAction[$method] as $callback) {
call_user_func($callback);
}
}
}
}
以上方法可以根据实际需求选择或组合使用,构建灵活的Hook系统。







