PHP事件驱动架构与实现

发布时间:2026/6/1 15:32:17

PHP事件驱动架构与实现 PHP事件驱动架构与实现事件驱动架构让系统的各个组件之间松耦合地通信。框架中的事件系统是观察者模式的进阶实现。今天实现一个完整的事件系统。事件系统包含三个核心组件事件类、监听器类和调度器。phpabstract class Event{protected bool $propagationStopped false;protected string $name ;public function getName(): string{if (empty($this-name)) {$this-name (new ReflectionClass($this))-getShortName();}return $this-name;}public function stopPropagation(): void{$this-propagationStopped true;}public function isPropagationStopped(): bool{return $this-propagationStopped;}}interface ListenerInterface{public function handle(Event $event): void;}class EventDispatcher{private array $listeners [];private array $sorted [];private array $loaded [];public function addListener(string $eventName, callable $listener, int $priority 0): void{$this-listeners[$eventName][$priority][] $listener;unset($this-sorted[$eventName]);}public function addSubscriber(EventSubscriber $subscriber): void{foreach ($subscriber-getSubscribedEvents() as $eventName $params) {if (is_string($params)) {$this-addListener($eventName, [$subscriber, $params]);} elseif (is_array($params)) {foreach ($params as $param) {if (is_string($param)) {$this-addListener($eventName, [$subscriber, $param]);} elseif (is_array($param)) {$this-addListener($eventName, [$subscriber, $param[0]], $param[1] ?? 0);}}}}}public function dispatch(Event $event): void{$eventName $event-getName();$listeners $this-getListeners($eventName);foreach ($listeners as $listener) {if ($event-isPropagationStopped()) {break;}$listener($event, $eventName, $this);}}public function getListeners(string $eventName null): array{if ($eventName ! null) {if (!isset($this-sorted[$eventName])) {$this-sortListeners($eventName);}return $this-sorted[$eventName];}foreach (array_keys($this-listeners) as $name) {if (!isset($this-sorted[$name])) {$this-sortListeners($name);}}return $this-sorted;}public function hasListeners(string $eventName): bool{return !empty($this-listeners[$eventName]);}public function removeListener(string $eventName, callable $listener): void{if (!isset($this-listeners[$eventName])) return;foreach ($this-listeners[$eventName] as $priority $listeners) {foreach ($listeners as $key $value) {if ($value $listener) {unset($this-listeners[$eventName][$priority][$key]);}}}unset($this-sorted[$eventName]);}private function sortListeners(string $eventName): void{$this-sorted[$eventName] [];if (isset($this-listeners[$eventName])) {krsort($this-listeners[$eventName]);$this-sorted[$eventName] array_merge(...$this-listeners[$eventName]);}}}interface EventSubscriber{public static function getSubscribedEvents(): array;}?// 具体事件class UserRegistered extends Event{public function __construct(public int $userId,public string $name,public string $email) {}}class OrderPaid extends Event{public function __construct(public string $orderId,public float $amount,public int $userId) {}}class UserLoggedIn extends Event{public function __construct(public int $userId,public string $ip) {}}// 监听器class SendWelcomeEmailListener{public function handle(UserRegistered $event): void{echo 发送欢迎邮件至 {$event-email}\n;}}class UpdateUserStatsListener{public function handle(UserRegistered $event): void{echo 更新用户统计: {$event-userId}\n;}}class LogFailedLoginListener{public function handle(UserLoggedIn $event): void{echo 记录登录日志: 用户{$event-userId} 来自 {$event-ip}\n;}}class OrderSubscriber implements EventSubscriber{public static function getSubscribedEvents(): array{return [OrderPaid::class [[updateInventory, 10],[sendReceipt, 5],[notifyAdmin, 0],],];}public function updateInventory(OrderPaid $event): void{echo 更新库存: 订单{$event-orderId}\n;}public function sendReceipt(OrderPaid $event): void{echo 发送收据: 订单{$event-orderId} 金额{$event-amount}\n;}public function notifyAdmin(OrderPaid $event): void{echo 通知管理员: 订单{$event-orderId}已支付\n;}}// 使用事件系统$dispatcher new EventDispatcher();// 注册监听器$dispatcher-addListener(UserRegistered::class, function (UserRegistered $event) {echo [闭包] 用户注册: {$event-name} ({$event-email})\n;}, 10);$dispatcher-addListener(UserRegistered::class, [new SendWelcomeEmailListener(), handle], 5);$dispatcher-addListener(UserRegistered::class, [new UpdateUserStatsListener(), handle], 0);$dispatcher-addListener(UserLoggedIn::class, function (UserLoggedIn $event) {echo 用户{$event-userId}登录成功\n;});$dispatcher-addSubscriber(new OrderSubscriber());// 触发事件$dispatcher-dispatch(new UserRegistered(1, 张三, zhangsantest.com));echo str_repeat(-, 40) . \n;$dispatcher-dispatch(new OrderPaid(ORD-2024-0001, 299.00, 1));?事件系统相比简单的观察者模式有几个增强。支持事件传播停止高优先级的监听器可以阻止后续监听器执行。支持事件订阅者一个类可以监听多个事件。这些特性让事件系统在大型应用中更加实用。

相关新闻