maxkaemmerer / events
提供事件、事件订阅者通信的接口和实现
Requires
- php: >=7.2
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-08 07:51:00 UTC
README
描述
这个库提供了简单事件、事件订阅者、事件信使结构的接口和实现。
这当然不是原创想法,但这是我的首选并且相对简单的实现。
代码已经完全测试,但我对在生产环境中使用不承担责任。
自行承担风险。
安装
composer require maxkaemmerer/events
用法
通常,您不希望手动订阅每个 EventSubscriber。您可能希望通过容器或服务管理器使用依赖注入。
(例如,对于Symfony框架,可以使用CompilerPass)
您还希望在需要的地方通过依赖注入注入EventCourier本身。
如果您需要更高级的功能,可以自由地创建自己的EventCourier、Subscription和Payload实现。
订阅事件订阅者
将一个EventSubscriber订阅到EventCourier。EventSubscriber的subscription()方法返回一个Subscription,其中包含EventSubscriber订阅的事件名称及其希望被通知的优先级。
(优先级越高,EventSubscriber在事件发生时被通知的时间越早,假设还有其他优先级较低的EventSubscriber)。
最佳实践是使用事件的完全限定类名。例如 MyEvent::class
EventSubscriber::on($event)方法是实际领域逻辑发生的地方。
您可以将服务、容器或您需要的任何其他内容注入到您的EventSubscriber中。
$courier = new SimpleEventCourier();
$courier->subscribe(new class implements EventSubscriber
{
/**
* @param Event $event
*/
public function on(Event $event): void
{
echo 'Notify Shipping!' . PHP_EOL;
}
/**
* @return EventSubscription
*/
public function subscription(): EventSubscription
{
return Subscription::fromEventNameAndPriority('PaymentReceived', 50);
}
});
分发事件
分发一个Event会导致EventCourier通知所有订阅者,这些订阅者的Subscription::event()方法与指定名称的Event匹配,并按优先级顺序调用他们的EventSubscriber::on($event)方法。
重要:EventSubscriber和EventCourier永远不会返回任何内容。
...
// The EventSubscriber was subscribed
echo 'Payment received.' . PHP_EOL;
$courier->dispatch(new class implements Event
{
public function payload(): EventPayload
{
// the payload should of course be built or set in the constructor
return Payload::fromArray(['price' => '99.99€', 'method' => 'creditCard', 'timestamp' => '12345678']);
}
public function name(): string
{
// best practice would be using the fully qualified class name MyEvent::class
return 'PaymentReceived';
}
});
结果
Payment received.
Notify Shipping!
完整示例
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MaxKaemmerer\Events\Event;
use MaxKaemmerer\Events\EventPayload;
use MaxKaemmerer\Events\EventSubscriber;
use MaxKaemmerer\Events\EventSubscription;
use MaxKaemmerer\Events\Implementations\Payload;
use MaxKaemmerer\Events\Implementations\SimpleEventCourier;
use MaxKaemmerer\Events\Implementations\Subscription;
$courier = new SimpleEventCourier();
$courier->subscribe(new class implements EventSubscriber
{
/**
* @param Event $event
*/
public function on(Event $event): void
{
echo 'Notify Shipping!' . PHP_EOL;
}
/**
* @return EventSubscription
*/
public function subscription(): EventSubscription
{
return Subscription::fromEventNameAndPriority('PaymentReceived', 50);
}
});
$courier->subscribe(new class implements EventSubscriber
{
/**
* @param Event $event
*/
public function on(Event $event): void
{
echo 'Send Receipt! Payed: ' . $event->payload()->get('price') . PHP_EOL;
}
/**
* @return EventSubscription
*/
public function subscription(): EventSubscription
{
return Subscription::fromEventNameAndPriority('PaymentReceived', 60);
}
});
echo 'Payment received.' . PHP_EOL;
$courier->dispatch(new class implements Event
{
public function payload(): EventPayload
{
// the payload should of course be built or set in the constructor
return Payload::fromArray(['price' => '99.99€', 'method' => 'creditCard', 'timestamp' => '12345678']);
}
public function name(): string
{
// best practice would be using the fully qualified class name MyEvent::class
return 'PaymentReceived';
}
});
结果
Payment received.
Send Receipt! Payed: 99.99€
Notify Shipping!
发送收据!已支付:99.99€首先被回显,因为相应的EventSubscriber的Subscription::priority()优先级更高。