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, $params = []) {
global $hooks;
if (isset($hooks[$hook_name])) {
foreach ($hooks[$hook_name] as $callback) {
call_user_func_array($callback, $params);
}
}
}
面向对象实现
采用面向对象方式创建更结构化的Hook系统:
class HookSystem {
private $hooks = [];
public function add($name, $callback) {
$this->hooks[$name][] = $callback;
}
public function run($name, $params = []) {
if (!empty($this->hooks[$name])) {
foreach ($this->hooks[$name] as $callback) {
call_user_func_array($callback, $params);
}
}
}
}
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;
ksort($wp_actions[$tag]);
}
function do_action($tag, $arg = '') {
global $wp_actions;
if (isset($wp_actions[$tag])) {
foreach ($wp_actions[$tag] as $priority => $functions) {
foreach ($functions as $function) {
call_user_func($function, $arg);
}
}
}
}
事件驱动实现
使用SplSubject和SplObserver接口实现观察者模式:
class Event implements \SplSubject {
private $observers;
public function __construct() {
$this->observers = new \SplObjectStorage();
}
public function attach(\SplObserver $observer) {
$this->observers->attach($observer);
}
public function detach(\SplObserver $observer) {
$this->observers->detach($observer);
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
PSR-14兼容实现
遵循PSR-14标准的事件分发器实现:
interface EventDispatcherInterface {
public function dispatch(object $event);
}
class EventDispatcher implements EventDispatcherInterface {
private $listeners = [];
public function addListener(string $eventName, callable $listener) {
$this->listeners[$eventName][] = $listener;
}
public function dispatch(object $event) {
foreach ($this->listeners[get_class($event)] ?? [] as $listener) {
$listener($event);
}
}
}
实际应用示例
在MVC框架中实现前置和后置钩子:
class Controller {
protected $beforeFilters = [];
protected $afterFilters = [];
public function beforeFilter($method, $callback) {
$this->beforeFilters[$method][] = $callback;
}
public function afterFilter($method, $callback) {
$this->afterFilters[$method][] = $callback;
}
protected function runFilters($type, $method) {
$var = $type.'Filters';
if (!empty($this->$var[$method])) {
foreach ($this->$var[$method] as $filter) {
call_user_func([$this, $filter]);
}
}
}
}
每种实现方式适用于不同场景,从简单的函数钩子到符合标准的事件系统,可根据项目需求选择合适的方法。







