Symfony事件系统基于观察者模式实现,通过EventDispatcher组件完成事件的调度工作,开发者可以通过事件监听和触发机制,让不同模块在不直接依赖的情况下完成通信,减少代码耦合度。

Symfony事件系统核心概念
事件系统主要包含几个核心角色:EventDispatcher是事件调度器,负责管理监听器和触发事件;Event是事件对象,可以携带自定义数据传递给监听器;监听器是处理事件的具体逻辑,订阅器则可以批量注册多个事件的监听逻辑。
自定义事件类
首先我们需要创建一个自定义的事件类,继承Symfony的Event基类,用来传递事件相关的数据:
<?php
namespace App\Event;
use Symfony\Contracts\EventDispatcher\Event;
class UserRegisterEvent extends Event
{
// 定义事件名称常量,方便后续调用
public const NAME = 'user.register';
private string $username;
public function __construct(string $username)
{
$this->username = $username;
}
public function getUsername(): string
{
return $this->username;
}
}注册事件监听器
监听器可以是普通的函数、类方法,我们这里以类方法为例,创建一个监听器类:
<?php
namespace App\EventListener;
use App\Event\UserRegisterEvent;
class UserRegisterListener
{
public function onUserRegister(UserRegisterEvent $event)
{
$username = $event->getUsername();
// 这里可以写发送欢迎邮件、记录注册日志等逻辑
echo "用户 {$username} 注册成功,已触发注册事件监听逻辑" . PHP_EOL;
}
}如果是使用Symfony框架,我们可以在配置文件中注册监听器,或者在监听器类上添加@AsEventListener注解:
<?php
namespace App\EventListener;
use App\Event\UserRegisterEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
#[AsEventListener(event: UserRegisterEvent::NAME)]
class UserRegisterListener
{
public function onUserRegister(UserRegisterEvent $event)
{
$username = $event->getUsername();
echo "用户 {$username} 注册成功,已触发注册事件监听逻辑" . PHP_EOL;
}
}触发事件
在需要触发事件的地方,我们注入EventDispatcher,然后创建事件对象并触发:
<?php
namespace App\Service;
use App\Event\UserRegisterEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class UserService
{
private EventDispatcherInterface $eventDispatcher;
public function __construct(EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
public function register(string $username): void
{
// 这里写用户注册的核心逻辑,比如写入数据库
echo "用户 {$username} 注册流程核心逻辑执行完成" . PHP_EOL;
// 触发注册事件
$event = new UserRegisterEvent($username);
$this->eventDispatcher->dispatch($event, UserRegisterEvent::NAME);
}
}事件订阅器使用
如果我们需要一个类监听多个事件,可以使用事件订阅器,实现EventSubscriberInterface接口:
<?php
namespace App\EventSubscriber;
use App\Event\UserRegisterEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserEventSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
UserRegisterEvent::NAME => 'onUserRegister',
// 可以继续添加其他事件的监听配置
];
}
public function onUserRegister(UserRegisterEvent $event): void
{
$username = $event->getUsername();
echo "订阅器监听到用户 {$username} 注册事件" . PHP_EOL;
}
}事件优先级说明
同一个事件可以注册多个监听器,默认情况下监听器按照注册顺序执行,我们可以通过设置优先级调整执行顺序,优先级数值越大,越先执行:
#[AsEventListener(event: UserRegisterEvent::NAME, priority: 10)]
class HighPriorityListener
{
public function onUserRegister(UserRegisterEvent $event)
{
echo "高优先级监听器执行" . PHP_EOL;
}
}
#[AsEventListener(event: UserRegisterEvent::NAME, priority: 5)]
class LowPriorityListener
{
public function onUserRegister(UserRegisterEvent $event)
{
echo "低优先级监听器执行" . PHP_EOL;
}
}事件传播停止
如果某个监听器执行后不希望后续监听器继续执行,可以在事件对象上调用stopPropagation方法:
public function onUserRegister(UserRegisterEvent $event)
{
// 执行逻辑后停止事件传播
$event->stopPropagation();
}之后可以通过$event->isPropagationStopped()判断事件是否已经停止传播。
Symfony事件系统事件监听事件触发EventDispatcher修改时间:2026-06-07 01:46:46