php 钩子 实现
PHP 钩子实现方法
钩子(Hook)是一种常见的编程模式,允许在特定事件发生时插入自定义代码。PHP中可以通过多种方式实现钩子机制。
使用函数和数组存储钩子
$hooks = [];
function add_hook($hook_name, $callback) {
global $hooks;
$hooks[$hook_name][] = $callback;
}
function execute_hook($hook_name, $params = []) {
global $hooks;
if (isset($hooks[$hook_name])) {
foreach ($hooks[$hook_name] as $callback) {
call_user_func_array($callback, $params);
}
}
}
// 使用示例
add_hook('before_save', function($data) {
echo "Processing data before save: " . print_r($data, true);
});
$data = ['id' => 1, 'name' => 'Test'];
execute_hook('before_save', [$data]);
面向对象实现方式
class HookManager {
private $hooks = [];
public function add($hook_name, $callback) {
$this->hooks[$hook_name][] = $callback;
}
public function execute($hook_name, $params = []) {
if (isset($this->hooks[$hook_name])) {
foreach ($this->hooks[$hook_name] as $callback) {
call_user_func_array($callback, $params);
}
}
}
}
// 使用示例
$hookManager = new HookManager();
$hookManager->add('after_login', function($user) {
echo "User {$user} logged in successfully";
});
$hookManager->execute('after_login', ['admin']);
WordPress风格的钩子实现
class HookSystem {
private static $actions = [];
private static $filters = [];
public static function add_action($hook, $callback, $priority = 10) {
self::$actions[$hook][$priority][] = $callback;
}
public static function do_action($hook, $args = []) {
if (isset(self::$actions[$hook])) {
ksort(self::$actions[$hook]);
foreach (self::$actions[$hook] as $priority => $callbacks) {
foreach ($callbacks as $callback) {
call_user_func_array($callback, $args);
}
}
}
}
public static function add_filter($hook, $callback, $priority = 10) {
self::$filters[$hook][$priority][] = $callback;
}
public static function apply_filters($hook, $value, $args = []) {
if (isset(self::$filters[$hook])) {
ksort(self::$filters[$hook]);
foreach (self::$filters[$hook] as $priority => $callbacks) {
foreach ($callbacks as $callback) {
$value = call_user_func_array($callback, array_merge([$value], $args));
}
}
}
return $value;
}
}
// 使用示例
HookSystem::add_filter('content_filter', function($content) {
return strtoupper($content);
});
$content = "hello world";
$filtered = HookSystem::apply_filters('content_filter', $content);
echo $filtered; // 输出: HELLO WORLD
事件驱动实现
interface HookListener {
public function handle($event);
}
class HookDispatcher {
private $listeners = [];
public function addListener($event_name, HookListener $listener) {
$this->listeners[$event_name][] = $listener;
}
public function dispatch($event_name, $event) {
if (isset($this->listeners[$event_name])) {
foreach ($this->listeners[$event_name] as $listener) {
$listener->handle($event);
}
}
}
}
// 使用示例
class UserRegisteredListener implements HookListener {
public function handle($event) {
echo "User {$event['username']} registered with email {$event['email']}";
}
}
$dispatcher = new HookDispatcher();
$dispatcher->addListener('user.registered', new UserRegisteredListener());
$event = ['username' => 'john', 'email' => 'john@example.com'];
$dispatcher->dispatch('user.registered', $event);
钩子实现注意事项
- 优先考虑使用面向对象方式实现,更易于维护和扩展
- 为钩子添加优先级支持,可以控制回调执行顺序
- 考虑添加移除钩子的功能
- 大型项目建议使用成熟的PHP事件系统如Symfony EventDispatcher
以上实现方式可根据项目需求选择或组合使用,简单的钩子系统可以使用函数数组方式,复杂的系统建议采用面向对象或事件驱动方式。







