klsoft/yii3-symfony-messenger

The package provides an easy way to integrate the Yii 3 framework with the Symfony Messenger

Maintainers

Package info

github.com/klsoft-web/yii3-symfony-messenger

pkg:composer/klsoft/yii3-symfony-messenger

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-07-27 04:04 UTC

This package is auto-updated.

Last update: 2026-07-27 04:08:18 UTC


README

The package provides an easy way to integrate the Yii 3 framework with the Symfony Messenger.

Requirement

  • PHP 8.2 or higher.

Installation

composer require klsoft/yii3-symfony-messenger

How to use

1. Create a Message and Handler.

final readonly class MyMessage
{
    public function __construct(public string $content)
    {
    }
}
use Psr\Log\LoggerInterface;

final readonly class MyMessageHandler
{
    public function __construct(private LoggerInterface $logger)
    {
    }
    public function __invoke(MyMessage $message): void
    {
        // ...
       $this->logger->info("The message with the content '$message->content' has been received.");
    }
}

2. Configure the Symfony Messenger dependencies in the config/common/di/application.php file.

Example uses the symfony/doctrine-messenger package for transport:

use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Tools\Console\EntityManagerProvider;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
use Klsoft\Yii3SymfonyMessenger\ServiceProvider;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection;
use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport;
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
use Symfony\Component\Messenger\Command\DebugCommand;
use Symfony\Component\Messenger\Command\FailedMessagesRemoveCommand;
use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand;
use Symfony\Component\Messenger\Command\FailedMessagesShowCommand;
use Symfony\Component\Messenger\Command\SetupTransportsCommand;
use Symfony\Component\Messenger\Command\StatsCommand;
use Symfony\Component\Messenger\EventListener\StopWorkerOnRestartSignalListener;
use Symfony\Component\Messenger\Handler\HandlersLocator;
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware;
use Symfony\Component\Messenger\Middleware\SendMessageMiddleware;
use Symfony\Component\Messenger\RoutableMessageBus;
use Symfony\Component\Messenger\Transport\Sender\SendersLocator;
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
use Symfony\Contracts\Service\ServiceProviderInterface;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Definitions\Reference;

class_alias(MessageBus::class, 'MyMessageBus');

return [
    // ...
    CacheItemPoolInterface::class => static function (ContainerInterface $container) {
        return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime'));
    }, //One of the following adapters should be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth.

    Configuration::class => static function (ContainerInterface $container) use ($params) {
        $config = ORMSetup::createAttributeMetadataConfiguration( // on PHP >= 8.4, use ORMSetup::createAttributeMetadataConfig()
            paths: $params['doctrine']['paths'],
            isDevMode: $params['doctrine']['isDevMode'],
            cache: $container->get(CacheItemPoolInterface::class));
        $config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED);
        return $config;
    },

    EntityManagerInterface::class => static function (ContainerInterface $container) use ($params) {
        $configuration = $container->get(Configuration::class);
        return new EntityManager(
            DriverManager::getConnection(
                $params['doctrine']['connection'],
                $configuration
            ),
            $configuration);
    },
    EntityManagerProvider::class => SingleManagerProvider::class,

    SerializerInterface::class => PhpSerializer::class,
    'DoctrineTransport' => static function (ContainerInterface $container) use ($params) {
        $configuration = $container->get(Configuration::class);
        $connection = new Connection([], DriverManager::getConnection(
            $params['doctrine']['connection'],
            $configuration
        ));
        return new DoctrineTransport($connection, $container->get(SerializerInterface::class));
    },

    MyMessageBus::class => static function (ContainerInterface $container) {
        return new MyMessageBus([
            new SendMessageMiddleware(sendersLocator: new SendersLocator([MyMessage::class => ['DoctrineTransport']], $container)),
            new HandleMessageMiddleware(new HandlersLocator([
                MyMessage::class => [$container->get(MyMessageHandler::class)]
            ])),
        ]);
    },

    EventDispatcherInterface::class => static function (ContainerInterface $container) {
        $eventDispatcher = new EventDispatcher();
        $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class));
        return $eventDispatcher;
    },
    ServiceProviderInterface::class => [
        'class' => ServiceProvider::class,
        '__construct()' => [
            'container' => Reference::to(ContainerInterface::class),
            'serviceMap' => [
                'DoctrineTransport' => DoctrineTransport::class
            ]
        ],
    ],

    ConsumeMessagesCommand::class => [
        '__construct()' => [
            'routableBus' => Reference::to(RoutableMessageBus::class),
            'receiverLocator' => Reference::to(ContainerInterface::class),
            'eventDispatcher' => Reference::to(EventDispatcherInterface::class),
            'logger' => Reference::to(LoggerInterface::class),
            'receiverNames' => [
                'DoctrineTransport'
            ],
            'rateLimiterLocator' => null
        ],
    ],
    DebugCommand::class => [
        '__construct()' => [
            'mapping' => [
                MyMessageBus::class => [Reference::to(MyMessageHandler::class)]
            ]
        ],
    ],
    FailedMessagesRemoveCommand::class => [
        '__construct()' => [
            'globalFailureReceiverName' => null,
            'failureTransports' => Reference::to(ServiceProviderInterface::class)
        ],
    ],
    FailedMessagesRetryCommand::class => [
        '__construct()' => [
            'globalReceiverName' => null,
            'failureTransports' => Reference::to(ServiceProviderInterface::class),
            'messageBus' => Reference::to(MyMessageBus::class),
            'eventDispatcher' => Reference::to(EventDispatcherInterface::class),
            'logger' => Reference::to(LoggerInterface::class),
        ],
    ],
    FailedMessagesShowCommand::class => [
        '__construct()' => [
            'globalFailureReceiverName' => null,
            'failureTransports' => Reference::to(ServiceProviderInterface::class)
        ],
    ],
    SetupTransportsCommand::class => [
        '__construct()' => [
            'transportLocator' => Reference::to(ContainerInterface::class),
            'transportNames' => [
                'DoctrineTransport'
            ]
        ],
    ],
    StatsCommand::class => [
        '__construct()' => [
            'transportLocator' => Reference::to(ContainerInterface::class),
            'transportNames' => [
                'DoctrineTransport'
            ]
        ],
    ],
];

3. Dispatch a message.

Example:

use MyMessageBus;
use Psr\Http\Message\ResponseInterface;

final readonly class MyController
{
    public function __construct(private MyMessageBus $bus)
    {
    }
    
    public function sendMessage(): ResponseInterface
    {
        $this->bus->dispatch(new MyMessage('Hello Symfony Messenger!'));
        // ...
    }
}

4. Consume messages.

Example:

./yii symfony:messenger:consume DoctrineTransport --bus=MyMessageBus --time-limit=3600

The following commands are currently available:

  • symfony:messenger:consume
  • symfony:messenger:debug
  • symfony:messenger:failed:remove
  • symfony:messenger:failed:retry
  • symfony:messenger:failed:show
  • symfony:messenger:setup-transports
  • symfony:messenger:stats
  • symfony:messenger:stop-workers

Display help for a command:

./yii <command> --help