spiral-packages / event-bus
基于 symfony 事件处理器的简单观察者模式实现,允许您订阅并监听应用程序内发生的各种事件。
Requires
- php: ^8.1
- spiral/attributes: ^2.8 || ^3.0
- spiral/boot: ^3.0
- spiral/config: ^3.0
- spiral/core: ^3.0
- spiral/hmvc: ^3.0
- spiral/queue: ^3.0
- spiral/tokenizer: ^3.0
- symfony/event-dispatcher: ^6.0
Requires (Dev)
- spiral/testing: ^2.0
- vimeo/psalm: ^4.9
This package is auto-updated.
Last update: 2024-09-07 06:14:17 UTC
README
订阅并监听应用程序内发生的各种事件。
需求
请确保您的服务器配置了以下 PHP 版本和扩展
- PHP 8.0+
- Spiral 框架 2.9+
安装
您可以通过 composer 安装此包
composer require spiral-packages/event-bus
安装包后,您需要从包中注册引导加载器。
protected const LOAD = [ // ... \Spiral\EventBus\Bootloader\EventBusBootloader::class, ];
或
namespace App\Bootloader; use Spiral\EventBus\Bootloader\EventBusBootloader as BaseBootloader class EventBusBootloader extends BaseBootloader { protected const LISTENS = [ \App\Event\UserCreated::class => [ \App\Listener\SendWelcomeMessageListener::class ], //... ]; }
使用
首先需要创建配置文件 app/config/event-bus.php
,其中您可以指定监听器。
<?php declare(strict_types=1); return [ 'queueConnection' => env('EVENT_BUS_QUEUE_CONNECTION'), // default queue connection for Listeners with \Spiral\EventBus\QueueableInterface 'discoverListeners' => env('EVENT_BUS_DISCOVER_LISTENERS', true), // Discover listeners with \Spiral\EventBus\Attribute\Listener attribute 'listeners' => [ UserDeleted::class => [ DeleteUserComments::class, ] ], 'interceptors' => [ BroadcastEventInterceptor::class ] ];
您还可以通过 Spiral\EventBus\ListenerRegistryInterface
注册监听器
class MyPackageBootloader extends Spiral\Boot\Bootloader\Bootloader { public function start(Spiral\EventBus\ListenerRegistryInterface $registry) { $registry->addListener(UserDeleted::class, DeleteUserComments::class); } }
事件示例
class UserDeleted { public function __construct(public string $name) {} }
监听器示例
确保在事件处理方法中使用变量
$event
。这是必需的。
class DeleteUserComments { public function __construct(private CommentService $service) {} public function __invoke(UserDeleted $event) { $this->service->deleteCommentsForUser($event->name); } }
带有属性的监听器示例
如果您使用带有属性 'discoverListeners' = true
的监听器,则无需注册它们,它们将自动注册。
use Spiral\EventBus\Attribute\Listener; class DeleteUserComments { public function __construct(private CommentService $service) {} #[Listener] public function handleDeletedUser(UserDeleted $event) { $this->service->deleteCommentsForUser($event->usernname); } #[Listener] public function handleCreatedUser(UserCreated $event) { $this->service->creaateUserProfile($event->usernname); } #[Listener] public function notifyAdmins(UserCreated|UserDeleted $event) { $this->service->notifyAdmins($event->usernname); } }
需要在队列中处理的监听器示例
如果您想将监听器推送到队列中,可以添加 Spiral\EventBus\QueueableInterface
class DeleteUserComments implements \Spiral\EventBus\QueueableInterface { // ... }
事件分发
use Symfony\Component\EventDispatcher\EventDispatcherInterface; class UserService { public function __construct(private EventDispatcherInterface $events) {} public function deleteUserById(string $id): void { $user = User::findById($id); //.. $this->events->dispatch( new UserDeleted($user->username) ); } }
拦截器
该包提供方便的 Bootloader 以自动配置核心拦截器 Spiral\EventBus\Bootloader\EventBusBootloader
namespace App\Bootloader; use Spiral\EventBus\Bootloader\EventBusBootloader as BaseBootloader class EventBusBootloader extends BaseBootloader { protected const INTERCEPTORS = [ \App\Event\Interceptor\BroadcastEventInterceptor::class, //... ]; }
或通过配置 app/config/event-bus.php
<?php declare(strict_types=1); return [ // ... 'interceptors' => [ BroadcastEventInterceptor::class ] ];
namespace App\Event\Interceptor; use Spiral\Broadcasting\BroadcastInterface; class BroadcastEventInterceptor implements \Spiral\Core\CoreInterceptorInterface { public function __construct( private BroadcastInterface $broadcast ) {} public function process(string $eventName, string $action, array , CoreInterface $core): mixed { $event = $parameters['event']; // Event object $listeners = $parameters['listeners']; // array of invokable listeners $result = $core->callAction($eventName, $action, $parameters); if ($event instanceof ShouldBroadcastInterface) { $this->broadcast->publish( $event->getBroadcasTopics(), \json_encode($event->toBroadcast()) ); } return $result; } }
测试
composer test
如果您在应用程序中使用 spiral/testing
包,您还可以在测试用例中使用 trait Spiral\EventBus\Testing\InteractsWithEvents
class EventDispatcherTest extends TestCase { use \Spiral\EventBus\Testing\InteractsWithEvents; public function testDispatchEvent(): void { $events = $this->fakeEventDispatcher(); $this->getDispatcher()->dispatch(new SimpleEvent()); $events->assertListening(SimpleEvent::class, SimpleListener::class); $events->assertListening(SimpleEvent::class, ListenerWithAttributes::class, 'methodA'); $events->assertDispatched(SimpleEvent::class) $events->assertDispatched(SimpleEvent::class, function(SimpleEvent $event) { return $event->someProperty === 'foo'; }); $events->assertDispatchedTimes(SimpleEvent::class, 10); $events->assertNotDispatched(AnotherSimpleEvent::class); $events->assertNotDispatched(AnotherSimpleEvent::class); $events->assertNothingDispatched(); } }
变更日志
请参阅 CHANGELOG 了解最近更改的信息。
贡献
请参阅 CONTRIBUTING 了解详细信息。
安全漏洞
请查看我们的安全策略 以了解如何报告安全漏洞
致谢
许可证
MIT 许可证 (MIT)。请参阅 许可证文件 了解更多信息。