Subscribe and listen for various events that occur within your application.
Make sure that your server is configured with following PHP version and extensions:
- PHP 8.0+
- Spiral framework 2.9+
You can install the package via composer:
composer require spiral-packages/event-bus
After package install you need to register bootloader from the package.
protected const LOAD = [
// ...
\Spiral\EventBus\Bootloader\EventBusBootloader::class,
];
Note: if you are using
spiral-packages/discoverer
package , you don't need to register bootloader by yourself anymore.
At first need create config file app/config/event-bus.php
, where you can specify listeners.
<?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,
]
]
];
You can also register listeners via 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) {}
}
class DeleteUserComments
{
public function __construct(private CommentService $service) {}
public function __invoke(UserDeleted $event)
{
$this->service->deleteCommentsForUser($event->name);
}
}
If you are using listeners with attributes 'discoverListeners' = true
, you don't need to register them, they will be
registered automatically.
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);
}
}
If you want to push listener to a queue, you can add 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)
);
}
}
composer test
If you are using spiral/testing
package in your application, you can additionally
use trait Spiral\EventBus\Testing\InteractsWithEvents
in your tests cases.
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();
}
}
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.