本文目录导读:

在PHP项目中实现用户自定义事件,主要有以下几种常见方式,我会从简单到复杂依次介绍。
使用观察者模式(最推荐)
这是最常用的实现方式,Event类配合Listener/Handler。
基础实现
<?php
// 事件类
class Event
{
protected $name;
protected $data;
protected $stopped = false;
public function __construct($name, $data = [])
{
$this->name = $name;
$this->data = $data;
}
public function getName()
{
return $this->name;
}
public function getData()
{
return $this->data;
}
public function stopPropagation()
{
$this->stopped = true;
}
public function isPropagationStopped()
{
return $this->stopped;
}
}
// 事件分发器
class EventDispatcher
{
protected $listeners = [];
// 注册监听器
public function addListener($eventName, $callback, $priority = 0)
{
$this->listeners[$eventName][] = [
'callback' => $callback,
'priority' => $priority
];
}
// 触发事件
public function dispatch($eventName, Event $event = null)
{
if ($event === null) {
$event = new Event($eventName);
}
if (!isset($this->listeners[$eventName])) {
return $event;
}
// 按优先级排序
$listeners = $this->listeners[$eventName];
usort($listeners, function($a, $b) {
return $b['priority'] - $a['priority'];
});
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
break;
}
call_user_func($listener['callback'], $event);
}
return $event;
}
// 移除监听器
public function removeListener($eventName, $callback)
{
if (!isset($this->listeners[$eventName])) {
return;
}
foreach ($this->listeners[$eventName] as $key => $listener) {
if ($listener['callback'] === $callback) {
unset($this->listeners[$eventName][$key]);
}
}
}
}
// 使用示例
class UserService
{
protected $dispatcher;
public function __construct(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function register($username, $email)
{
// 用户注册逻辑...
// 触发注册事件
$event = new Event('user.registered', [
'username' => $username,
'email' => $email,
'time' => time()
]);
$this->dispatcher->dispatch('user.registered', $event);
return true;
}
}
// 创建分发器
$dispatcher = new EventDispatcher();
// 注册监听器
$dispatcher->addListener('user.registered', function(Event $event) {
$data = $event->getData();
echo "发送欢迎邮件给: " . $data['email'] . "\n";
});
$dispatcher->addListener('user.registered', function(Event $event) {
$data = $event->getData();
echo "记录日志: 用户 {$data['username']} 注册成功\n";
}, 10); // 优先级高
// 使用
$userService = new UserService($dispatcher);
$userService->register('张三', 'zhangsan@example.com');
使用PHP内置的SPL(标准PHP库)
<?php
class UserEvent extends SplSubject
{
protected $observers = [];
protected $data = [];
public function attach(SplObserver $observer)
{
$this->observers[] = $observer;
}
public function detach(SplObserver $observer)
{
foreach ($this->observers as $key => $obs) {
if ($obs === $observer) {
unset($this->observers[$key]);
}
}
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function setData($data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}
}
class EmailObserver implements SplObserver
{
public function update(SplSubject $subject)
{
$data = $subject->getData();
echo "发送邮件到: " . $data['email'] . "\n";
}
}
class LogObserver implements SplObserver
{
public function update(SplSubject $subject)
{
$data = $subject->getData();
echo "日志: 用户 {$data['username']} 操作\n";
}
}
// 使用
$event = new UserEvent();
$event->attach(new EmailObserver());
$event->attach(new LogObserver());
$event->setData([
'username' => '张三',
'email' => 'zhangsan@example.com'
]);
$event->notify();
基于类注解的事件系统(高级)
<?php
#[Attribute]
class Event
{
public string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
class EventAnnotationParser
{
public static function parse(string $className)
{
$reflection = new ReflectionClass($className);
$events = [];
foreach ($reflection->getMethods() as $method) {
$attributes = $method->getAttributes(Event::class);
foreach ($attributes as $attribute) {
$event = $attribute->newInstance();
$events[$event->name] = [
'class' => $className,
'method' => $method->getName()
];
}
}
return $events;
}
}
// 使用示例
class UserEventHandler
{
#[Event('user.registered')]
public function handleUserRegistered($data)
{
echo "处理用户注册事件: " . json_encode($data) . "\n";
}
#[Event('user.deleted')]
public function handleUserDeleted($data)
{
echo "处理用户删除事件: " . json_encode($data) . "\n";
}
}
// 自动注册事件
$events = EventAnnotationParser::parse(UserEventHandler::class);
// 可以自动注册到事件分发器
使用现有库(推荐生产环境)
Symfony EventDispatcher
// composer require symfony/event-dispatcher
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class UserRegisteredEvent extends Event
{
const NAME = 'user.registered';
protected $user;
public function __construct($user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
}
$dispatcher = new EventDispatcher();
$dispatcher->addListener(UserRegisteredEvent::NAME, function(UserRegisteredEvent $event) {
$user = $event->getUser();
echo "用户 {$user['name']} 注册成功\n";
});
$event = new UserRegisteredEvent(['name' => '张三', 'email' => 'test@test.com']);
$dispatcher->dispatch($event, UserRegisteredEvent::NAME);
Laravel 事件(如果你使用Laravel框架)
// 1. 创建事件类
// php artisan make:event UserRegistered
class UserRegistered
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user;
public function __construct($user)
{
$this->user = $user;
}
}
// 2. 创建监听器
// php artisan make:listener SendWelcomeEmail
class SendWelcomeEmail
{
public function handle(UserRegistered $event)
{
// 发送欢迎邮件
Mail::to($event->user->email)->send(new WelcomeMail($event->user));
}
}
// 3. 注册监听器 (EventServiceProvider.php)
protected $listen = [
UserRegistered::class => [
SendWelcomeEmail::class,
UpdateUserStats::class,
],
];
// 4. 触发事件
event(new UserRegistered($user));
最佳实践建议
命名规范
// 使用点号分隔的事件名 'user.registered' 'user.deleted' 'order.created' 'payment.completed'
事件基类
abstract class BaseEvent
{
protected $stopPropagation = false;
protected $data = [];
abstract public function getName(): string;
public function stopPropagation(): void
{
$this->stopPropagation = true;
}
public function isPropagationStopped(): bool
{
return $this->stopPropagation;
}
}
异步事件处理
// 对于耗时操作,考虑异步处理
$dispatcher->addListener('user.registered', function($event) {
// 发送到消息队列
Queue::push('SendEmailJob', ['user_id' => $event->getUserId()]);
}, -100); // 低优先级,异步处理
错误处理
$dispatcher->addListener('user.registered', function($event) {
try {
// 事件处理逻辑
} catch (\Exception $e) {
// 记录错误日志,但不影响主流程
Log::error('Event handler failed: ' . $e->getMessage());
}
});
- 小项目:使用观察者模式手动实现
- 中等项目:使用SPL或简单的事件分发器
- 大型项目:使用Symfony EventDispatcher或框架自带的事件系统
- 性能要求高:考虑事件队列和异步处理
选择哪种方式取决于你的项目规模、性能需求和团队技术栈,建议从简单的模式开始,随着需求增长逐步升级。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播