1. Go to this page and download the library: Download sbooker/domain-events library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
sbooker / domain-events example snippets
// src/Product.php
use Sbooker\DomainEvents\DomainEventCollector;
use Sbooker\DomainEvents\DomainEntity;
class Product implements DomainEntity
{
use DomainEventCollector;
public function __construct(UuidInterface $id, string $name)
{
// ...
// Записываем событие о том, что произошло
$this->publish(new ProductCreated($id, $name));
}
}
// src/ProductCreated.php
use Sbooker\DomainEvents\DomainEvent;
final class ProductCreated extends DomainEvent {
// ... ваш код события
}
// src/Infrastructure/OutboxPublisher.php
use Sbooker\DomainEvents\Publisher;
use Sbooker\DomainEvents\DomainEvent;
// Этот Publisher сохраняет события в репозиторий (например, в БД)
final class OutboxPublisher implements Publisher
{
private OutboxEventRepository $repository;
public function __construct(OutboxEventRepository $repository)
{
$this->repository = $repository;
}
public function publish(DomainEvent $event): void
{
$outboxEvent = new OutboxEvent($event);
$this->repository->add($outboxEvent);
}
}
// src/UseCase/CreateProduct/Handler.php
use Sbooker\DomainEvents\ActorAwarePublisher;
// 1. Создаем Publisher, который сохраняет события в БД
$publisher = new ActorAwarePublisher(
new OutboxPublisher($outboxEventRepository), // <-- Используем наш новый Publisher
new SymfonyActorStorage($security)
);
// 2. Выполняем бизнес-логику
$product = new Product(Uuid::uuid4(), 'Ноутбук');
$productRepository->add($product);
// 3. Передаем события в Publisher, который тоже сохранит их в БД
$product->dispatchEvents($publisher);
// 4. Коммитим транзакцию
// Doctrine EntityManager или ваш Unit of Work сохранит И продукт, И события в одной транзакции
$entityManager->flush();
// src/Command/ProcessOutboxEventsCommand.php
class ProcessOutboxEventsCommand extends Command
{
public function execute(): int
{
// findUnprocessed() из sbooker/domain-events-persistence может блокировать
// события для безопасной параллельной обработки.
$eventsToProcess = $this->outboxRepo->findUnprocessed();
foreach ($eventsToProcess as $outboxEvent) {
try {
// Напрямую вызываем нужный обработчик (Subscriber)
$this->eventSubscriber->handle($outboxEvent->getDomainEvent());
$this->outboxRepo->markAsProcessed($outboxEvent);
} catch (\Exception $e) {
// Логируем ошибку, событие будет обработано повторно.
$this->logger->error('Failed to process event', ['id' => $outboxEvent->getId(), 'error' => $e]);
}
}
$this->entityManager->flush();
return Command::SUCCESS;
}
}
// src/Command/RelayOutboxEventsCommand.php
class RelayOutboxEventsCommand extends Command
{
public function execute(): int
{
$eventsToRelay = $this->outboxRepo->findUnprocessed();
foreach ($eventsToRelay as $outboxEvent) {
try {
// Отправляем событие во внешнюю шину
$this->realMessageBroker->publish($outboxEvent->getDomainEvent());
$this->outboxRepo->markAsProcessed($outboxEvent);
} catch (\Exception $e) {
// Логируем ошибку, повторим отправку при следующем запуске.
$this->logger->error('Failed to relay event', ['id' => $outboxEvent->getId(), 'error' => $e]);
}
}
$this->entityManager->flush();
return Command::SUCCESS;
}
}
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.