PHP 怎么PHP 事件

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 事件

  1. 手动实现简单的事件系统(观察者模式)
  2. 使用第三方事件库:Symfony EventDispatcher
  3. Laravel 中的事件(最常用场景)
  4. 是否应该用“事件”?适用场景
  5. 常见误区

在 PHP 中,“事件”并不是语言内置的核心特性(不像 JavaScript 或 C# 那样),PHP 本身没有原生的 event 关键字或 addEventListener 函数。

我们可以通过 设计模式(如 观察者模式、事件驱动架构)或 第三方库(如 Symfony EventDispatcher)来实现“事件”的效果。

下面从 原生 PHP 手动实现使用组件 两个角度说明。


手动实现简单的事件系统(观察者模式)

这是最基础的方式,适合理解原理。

1 定义事件类

<?php
class Event
{
    protected $listeners = [];
    // 注册监听器
    public function on(string $eventName, callable $callback)
    {
        $this->listeners[$eventName][] = $callback;
    }
    // 触发事件
    public function trigger(string $eventName, $data = null)
    {
        if (isset($this->listeners[$eventName])) {
            foreach ($this->listeners[$eventName] as $callback) {
                $callback($data);
            }
        }
    }
}

2 使用示例

$event = new Event();
// 注册“用户注册成功”事件
$event->on('user.registered', function($user) {
    echo "发送欢迎邮件给:" . $user['email'] . PHP_EOL;
});
$event->on('user.registered', function($user) {
    echo "记录日志:" . $user['name'] . " 注册成功" . PHP_EOL;
});
// 模拟用户注册,触发事件
$user = ['name' => 'Alice', 'email' => 'alice@example.com'];
$event->trigger('user.registered', $user);

输出:

发送欢迎邮件给:alice@example.com
记录日志:Alice 注册成功

这就是最朴素的“事件”,完全由你自己控制流程。


使用第三方事件库:Symfony EventDispatcher

这是 PHP 生态中最主流、最规范的事件方案,很多框架(如 Laravel、Symfony、Drupal)都基于它。

1 安装

composer require symfony/event-dispatcher

2 定义事件类

use Symfony\Contracts\EventDispatcher\Event;
class UserRegisteredEvent extends Event
{
    const NAME = 'user.registered';
    public function __construct(public array $user) {}
}

3 编写监听器

class SendWelcomeEmailListener
{
    public function __invoke(UserRegisteredEvent $event)
    {
        echo "发送邮件给:" . $event->user['email'] . PHP_EOL;
    }
}
class LogUserRegistrationListener
{
    public function __invoke(UserRegisteredEvent $event)
    {
        echo "记录日志:" . $event->user['name'] . " 注册" . PHP_EOL;
    }
}

4 注册与触发

use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
// 注册监听器
$dispatcher->addListener(UserRegisteredEvent::NAME, new SendWelcomeEmailListener());
$dispatcher->addListener(UserRegisteredEvent::NAME, new LogUserRegistrationListener());
// 触发事件
$user = ['name' => 'Bob', 'email' => 'bob@example.com'];
$dispatcher->dispatch(new UserRegisteredEvent($user), UserRegisteredEvent::NAME);

输出:

发送邮件给:bob@example.com
记录日志:Bob 注册

优势:支持优先级、订阅器(Subscriber)、事件传播停止(stopPropagation),适合大型项目。


Laravel 中的事件(最常用场景)

如果你在使用 Laravel,它内置了完善的事件系统,基于 Symfony EventDispatcher 封装。

php artisan make:event UserRegistered
php artisan make:listener SendWelcomeEmail --event=UserRegistered

触发事件

event(new UserRegistered($user));

或使用 Event Facade:

Event::dispatch(new UserRegistered($user));

Laravel 还支持队列驱动的事件监听,适合发邮件等耗时操作。


是否应该用“事件”?适用场景

场景 推荐做法
简单的回调、钩子 手动实现观察者模式或直接函数回调
中等规模项目(无框架) 引入 symfony/event-dispatcher
Laravel / Symfony 项目 使用框架自带事件系统
超大型微服务架构 考虑消息队列(RabbitMQ、Kafka)实现事件驱动

常见误区

  • PHP 没有 “事件循环”:除非你使用 Swoole 或 ReactPHP,否则 PHP 的每个请求结束后所有变量销毁,事件仅限于单次请求生命周期内。
  • 事件不是异步的:默认情况下 PHP 的事件监听器是 同步阻塞 执行的,要实现异步,需结合进程或消息队列。

方法 复杂度 适用项目
手动实现(观察者模式) 学习/小工具
Symfony EventDispatcher 中型 PHP 项目
Laravel 事件系统 Laravel 项目
Swoole + 自定义事件 高性能网络应用

一句话:PHP 没有原生事件关键字,但通过观察者模式或第三方库可以轻松实现事件机制。

抱歉,评论功能暂时关闭!