提供事件、事件订阅者通信的接口和实现

v1.0.0 2018-07-21 16:04 UTC

This package is auto-updated.

Last update: 2024-09-08 07:51:00 UTC


README

Travis branch Coveralls github PHP from Packagist Packagist Packagist

描述

这个库提供了简单事件、事件订阅者、事件信使结构的接口和实现。

这当然不是原创想法,但这是我的首选并且相对简单的实现。

代码已经完全测试,但我对在生产环境中使用不承担责任。

自行承担风险。

安装

composer require maxkaemmerer/events

用法

通常,您不希望手动订阅每个 EventSubscriber。您可能希望通过容器或服务管理器使用依赖注入。

(例如,对于Symfony框架,可以使用CompilerPass)

您还希望在需要的地方通过依赖注入注入EventCourier本身。

如果您需要更高级的功能,可以自由地创建自己的EventCourierSubscriptionPayload实现。

订阅事件订阅者

将一个EventSubscriber订阅到EventCourierEventSubscribersubscription()方法返回一个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)方法。

重要:EventSubscriberEventCourier永远不会返回任何内容。

...

// 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€首先被回显,因为相应的EventSubscriberSubscription::priority()优先级更高。