Symfony Messenger: āļ„āļīāļ§, Worker āđāļĨāļ°āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄ Async āļŠāļģāļŦāļĢāļąāļšāļŠāļąāļĄāļ āļēāļĐāļ“āđŒāļ‡āļēāļ™ 2026

āļ„āļđāđˆāļĄāļ·āļ­āđ€āļŠāļīāļ‡āļĨāļķāļ Symfony Messenger: message bus, transport, worker, middleware āļ›āđ‰āļ­āļ‡āļāļąāļ™āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģ, āļāļĨāļĒāļļāļ—āļ˜āđŒ retry āđāļĨāļ° streaming AMQP āđƒāļ™ Symfony 7.3+

āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄ Symfony Messenger āļ„āļīāļ§āđāļĨāļ° worker āđāļšāļš async

Symfony Messenger āđ€āļ›āđ‡āļ™āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•āđŒāļŦāļĨāļąāļāļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļ‡āļēāļ™āđāļšāļšāļ­āļ°āļ‹āļīāļ‡āđ‚āļ„āļĢāļ™āļąāļŠāđƒāļ™āļĢāļ°āļšāļšāļ™āļīāđ€āļ§āļĻ PHP āļŠāļĄāļąāļĒāđƒāļŦāļĄāđˆ āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•āđŒāļ™āļĩāđ‰āļĄāļ­āļš message bus āļ—āļĩāđˆāļĄāļĩāđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļŠāļąāļ”āđ€āļˆāļ™, transport āļ—āļĩāđˆāļāļģāļŦāļ™āļ”āļ„āđˆāļēāđ„āļ”āđ‰āļŦāļĨāļēāļāļŦāļĨāļēāļĒ āđāļĨāļ° worker āļ—āļĩāđˆāļ–āļđāļāļ„āļ§āļšāļ„āļļāļĄāļ­āļĒāđˆāļēāļ‡āļĢāļąāļ”āļāļļāļĄ āļ”āđ‰āļ§āļĒ Symfony 7.3 āđāļĨāļ°āđāļœāļ™āļ‡āļēāļ™āļŠāļđāđˆāđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™ 8.0 āļŸāļĩāđ€āļˆāļ­āļĢāđŒāđƒāļŦāļĄāđˆāļ­āļĒāđˆāļēāļ‡ middleware āļ›āđ‰āļ­āļ‡āļāļąāļ™āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģ, streaming AMQP āđāļĨāļ° Doctrine keepalive āļ—āļģāđƒāļŦāđ‰ Messenger āļĄāļĩāļ„āļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļ–āđ€āļ—āļĩāļĒāļšāđ€āļ—āđˆāļēāļāļąāļšāļĢāļ°āļšāļšāļ„āļīāļ§āđ€āļ‰āļžāļēāļ°āļ—āļēāļ‡āļ­āļĒāđˆāļēāļ‡ Laravel Horizon āļŦāļĢāļ·āļ­ Sidekiq

āļˆāļļāļ”āđ€āļ”āđˆāļ™āļ‚āļ­āļ‡ Symfony 7.3+ Messenger

Symfony 7.3 āđ€āļžāļīāđˆāļĄ DeduplicateMiddleware āļŠāļģāļŦāļĢāļąāļšāļāļĢāļ­āļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģāļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī, Doctrine transport keepalive āđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļŠāđˆāļ‡āļ‹āđ‰āļģāļ‚āļ­āļ‡āļ‡āļēāļ™āļ—āļĩāđˆāđƒāļŠāđ‰āđ€āļ§āļĨāļēāļ™āļēāļ™ āđāļĨāļ° attribute #[AsMessage] āļŠāļģāļŦāļĢāļąāļšāļāļģāļŦāļ™āļ” transport routing āđāļšāļšāļ›āļĢāļ°āļāļēāļĻ

āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄ Symfony Messenger: Bus, Transport āđāļĨāļ° Worker

āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•āđŒ Messenger āđāļĒāļāļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļšāļ­āļ­āļāđ€āļ›āđ‡āļ™āļŠāļēāļĄāļŠāđˆāļ§āļ™: āļāļēāļĢāļŠāđˆāļ‡ (bus), āļāļēāļĢāļ‚āļ™āļŠāđˆāļ‡ (transport) āđāļĨāļ°āļāļēāļĢāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨ (worker) āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ (message) āļ„āļ·āļ­āļ­āļ­āļšāđ€āļˆāļāļ•āđŒ PHP āļ˜āļĢāļĢāļĄāļ”āļē Handler āļ„āļ·āļ­āļ„āļĨāļēāļŠāļ—āļĩāđˆāļŠāļēāļĄāļēāļĢāļ–āđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰āļ‡āļēāļ™āđ„āļ”āđ‰ (invokable) Bus āđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­āļ—āļąāđ‰āļ‡āļŠāļ­āļ‡āļŠāđˆāļ§āļ™ āđ‚āļ”āļĒāļāļģāļŦāļ™āļ”āđ€āļŠāđ‰āļ™āļ—āļēāļ‡āļœāđˆāļēāļ™ middleware āđāļĨāļ°āđ€āļĨāļ·āļ­āļāļ—āļĩāđˆāļˆāļ° serialize āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđ„āļ›āļĒāļąāļ‡ transport āđ€āļžāļ·āđˆāļ­āļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāđāļšāļšāļ­āļ°āļ‹āļīāļ‡āđ‚āļ„āļĢāļ™āļąāļŠ

src/Message/InvoiceGenerated.phpphp
namespace App\Message;

final readonly class InvoiceGenerated
{
    public function __construct(
        public int $orderId,
        public string $customerEmail,
    ) {}
}

āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ™āļĩāđ‰āļšāļĢāļĢāļˆāļļāđ€āļ‰āļžāļēāļ°āļ‚āđ‰āļ­āļĄāļđāļĨāđāļšāļš scalar āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™ āđ„āļĄāđˆāđƒāļŠāđˆ entity āļ‚āļ­āļ‡ Doctrine āļāļēāļĢāļŠāđˆāļ‡ ID āđāļ—āļ™āļ­āļ­āļšāđ€āļˆāļāļ•āđŒāđ€āļ•āđ‡āļĄāļĢāļđāļ›āđāļšāļšāļŠāđˆāļ§āļĒāļŦāļĨāļĩāļāđ€āļĨāļĩāđˆāļĒāļ‡āļ›āļąāļāļŦāļē serialization āđāļĨāļ°āļ—āļģāđƒāļŦāđ‰āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđ€āļšāļē Handler āļˆāļ°āļ”āļķāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļĨāđˆāļēāļŠāļļāļ”āļˆāļēāļāļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ āļ“ āđ€āļ§āļĨāļēāļ—āļĩāđˆāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨ

src/MessageHandler/InvoiceGeneratedHandler.phpphp
namespace App\MessageHandler;

use App\Message\InvoiceGenerated;
use App\Service\InvoiceService;
use App\Service\MailerService;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
final readonly class InvoiceGeneratedHandler
{
    public function __construct(
        private InvoiceService $invoiceService,
        private MailerService $mailerService,
    ) {}

    public function __invoke(InvoiceGenerated $message): void
    {
        $pdf = $this->invoiceService->generatePdf($message->orderId);
        $this->mailerService->sendInvoice(
            $message->customerEmail,
            $pdf,
        );
    }
}

āļāļēāļĢ dispatch āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļˆāļēāļ controller āļŦāļĢāļ·āļ­ service āđƒāļŠāđ‰āđ€āļžāļĩāļĒāļ‡āļšāļĢāļĢāļ—āļąāļ”āđ€āļ”āļĩāļĒāļ§:

src/Controller/OrderController.phpphp
$this->bus->dispatch(new InvoiceGenerated(
    orderId: $order->getId(),
    customerEmail: $order->getCustomer()->getEmail(),
));

Bus āļˆāļ°āļ•āļąāļ”āļŠāļīāļ™āđƒāļˆāļ§āđˆāļēāļˆāļ°āļ—āļģāļ‡āļēāļ™āđāļšāļšāļ‹āļīāļ‡āđ‚āļ„āļĢāļ™āļąāļŠāļŦāļĢāļ·āļ­āļ­āļ°āļ‹āļīāļ‡āđ‚āļ„āļĢāļ™āļąāļŠāļ•āļēāļĄāļāļēāļĢāļāļģāļŦāļ™āļ”āļ„āđˆāļē routing āļ‚āļ­āļ‡ transport

āļāļēāļĢāļāļģāļŦāļ™āļ”āļ„āđˆāļē Transport āđāļĨāļ° Backend āļ„āļīāļ§

Messenger āļĢāļ­āļ‡āļĢāļąāļšāļŦāļĨāļēāļĒ backend: Doctrine DBAL, Redis, Amazon SQS, Beanstalkd, AMQP (RabbitMQ) āđāļĨāļ° streaming AMQP transport āļ—āļĩāđˆāđ€āļ›āļīāļ”āļ•āļąāļ§āđƒāļ™āļ›āļĩ 2025 āđāļ•āđˆāļĨāļ° transport āļ–āļđāļāļāļģāļŦāļ™āļ”āļ”āđ‰āļ§āļĒ DSN string

yaml
# config/packages/messenger.yaml
framework:
    messenger:
        failure_transport: failed

        transports:
            async_priority_high:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
                options:
                    queue_name: high
                retry_strategy:
                    max_retries: 3
                    delay: 1000
                    multiplier: 3
                    max_delay: 60000

            async_priority_low:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
                options:
                    queue_name: low
                retry_strategy:
                    max_retries: 5
                    delay: 5000
                    multiplier: 2

            failed:
                dsn: 'doctrine://default?queue_name=failed'

        routing:
            'App\Message\InvoiceGenerated': async_priority_high
            'App\Message\CleanupTempFiles': async_priority_low

āļāļēāļĢāđāļšāđˆāļ‡ transport āļ•āļēāļĄāļĨāļģāļ”āļąāļšāļ„āļ§āļēāļĄāļŠāļģāļ„āļąāļāļŠāđˆāļ§āļĒāđƒāļŦāđ‰āļ‡āļēāļ™āļ—āļĩāđˆāļ•āđ‰āļ­āļ‡āļ•āļ­āļšāļŠāļ™āļ­āļ‡āļĢāļ§āļ”āđ€āļĢāđ‡āļ§ (āļŠāļĢāđ‰āļēāļ‡āđƒāļšāđāļˆāđ‰āļ‡āļŦāļ™āļĩāđ‰) āļ–āļđāļāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļāđˆāļ­āļ™āļ‡āļēāļ™āļšāļģāļĢāļļāļ‡āļĢāļąāļāļĐāļē (āļĨāļšāđ„āļŸāļĨāđŒāļŠāļąāđˆāļ§āļ„āļĢāļēāļ§) āđāļ•āđˆāļĨāļ° transport āļĄāļĩāļāļĨāļĒāļļāļ—āļ˜āđŒ retry āļ‚āļ­āļ‡āļ•āļąāļ§āđ€āļ­āļ‡ āļ‹āļķāđˆāļ‡āļ›āļĢāļąāļšāđāļ•āđˆāļ‡āļ•āļēāļĄāļĢāļ°āļ”āļąāļšāļ„āļ§āļēāļĄāļŠāļģāļ„āļąāļāđāļĨāļ°āļ„āļļāļ“āļŠāļĄāļšāļąāļ•āļī idempotent āļ‚āļ­āļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ

Doctrine vs. Redis vs. AMQP

Transport āđāļšāļš Doctrine āđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āļāļēāļĢāđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļžāļ·āđ‰āļ™āļāļēāļ™āđ€āļžāļīāđˆāļĄāđ€āļ•āļīāļĄ āđāļ•āđˆāđ€āļžāļīāđˆāļĄāļ āļēāļĢāļ°āđƒāļŦāđ‰āļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ Redis āđƒāļŦāđ‰āļ„āļ§āļēāļĄāļŦāļ™āđˆāļ§āļ‡āļ•āđˆāļģāļāļ§āđˆāļēāļĄāļīāļĨāļĨāļīāļ§āļīāļ™āļēāļ—āļĩ AMQP (RabbitMQ) āļĄāļĩ routing āļ‚āļąāđ‰āļ™āļŠāļđāļ‡, dead-letter exchange āđāļĨāļ° streaming transport āđƒāļŦāļĄāđˆāļŠāļģāļŦāļĢāļąāļšāļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒ throughput āļŠāļđāļ‡ āļāļēāļĢāđ€āļĨāļ·āļ­āļāđƒāļŠāđ‰āļ„āļ§āļĢāļžāļīāļˆāļēāļĢāļ“āļēāļˆāļēāļāđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļžāļ·āđ‰āļ™āļāļēāļ™āļ—āļĩāđˆāļĄāļĩāļ­āļĒāļđāđˆāđāļĨāļ°āļ„āļ§āļēāļĄāļ•āđ‰āļ­āļ‡āļāļēāļĢāļ”āđ‰āļēāļ™ throughput

āļāļēāļĢāļˆāļąāļ”āļāļēāļĢ Worker āļ”āđ‰āļ§āļĒ Supervisor

Worker āļĢāļąāļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļˆāļēāļ transport āđƒāļ™āļŠāļ āļēāļžāđāļ§āļ”āļĨāđ‰āļ­āļĄ production āļ„āļģāļŠāļąāđˆāļ‡ messenger:consume āļˆāļ°āļ—āļģāļ‡āļēāļ™āļ āļēāļĒāđƒāļ•āđ‰ process manager āļ­āļĒāđˆāļēāļ‡ Supervisor āļŦāļĢāļ·āļ­ systemd

bash
# āļĢāļąāļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļĨāļģāļ”āļąāļšāļ„āļ§āļēāļĄāļŠāļģāļ„āļąāļāļŠāļđāļ‡āļāđˆāļ­āļ™ āļˆāļēāļāļ™āļąāđ‰āļ™āļĨāļģāļ”āļąāļšāļ„āļ§āļēāļĄāļŠāļģāļ„āļąāļāļ•āđˆāļģ
php bin/console messenger:consume async_priority_high async_priority_low \
    --memory-limit=128M \
    --time-limit=3600 \
    --limit=500

flag āļˆāļģāļāļąāļ”āļ—āļąāđ‰āļ‡āļŠāļēāļĄāļ•āļąāļ§āļ™āļĩāđ‰āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļĢāļąāđˆāļ§āđ„āļŦāļĨāļ‚āļ­āļ‡āļŦāļ™āđˆāļ§āļĒāļ„āļ§āļēāļĄāļˆāļģāđāļĨāļ°āļ—āļģāđƒāļŦāđ‰ worker āļĢāļĩāļŠāļ•āļēāļĢāđŒāļ—āđ€āļ›āđ‡āļ™āļĢāļ°āļĒāļ° Supervisor āļˆāļ°āđ€āļĢāļīāđˆāļĄāļāļĢāļ°āļšāļ§āļ™āļāļēāļĢāđƒāļŦāļĄāđˆāđ‚āļ”āļĒāļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļīāļŦāļĨāļąāļ‡āļˆāļēāļāļ­āļ­āļāđāļ•āđˆāļĨāļ°āļ„āļĢāļąāđ‰āļ‡

ini
; /etc/supervisor/conf.d/messenger-worker.conf
[program:messenger-consume]
command=php /var/www/app/bin/console messenger:consume async_priority_high async_priority_low --memory-limit=128M --time-limit=3600
user=www-data
numprocs=2
process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
startsecs=0
stopwaitsecs=30
stdout_logfile=/var/log/messenger-worker.log
stderr_logfile=/var/log/messenger-worker-error.log

āļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļē numprocs=2 āļˆāļ°āļŠāļĢāđ‰āļēāļ‡ worker āđāļšāļšāļ‚āļ™āļēāļ™āļŠāļ­āļ‡āļ•āļąāļ§ āļ—āļģāđƒāļŦāđ‰ throughput āđ€āļžāļīāđˆāļĄāđ€āļ›āđ‡āļ™āļŠāļ­āļ‡āđ€āļ—āđˆāļē āļŠāļēāļĄāļēāļĢāļ–āļ›āļĢāļąāļšāļˆāļģāļ™āļ§āļ™āļ•āļēāļĄ core CPU āļ‚āļ­āļ‡āđ€āļ‹āļīāļĢāđŒāļŸāđ€āļ§āļ­āļĢāđŒāđāļĨāļ°āđ€āļ§āļĨāļēāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ‚āđ‰āļ­āļ„āļ§āļēāļĄ

Pipeline Middleware āđāļĨāļ° CQRS āļ”āđ‰āļ§āļĒāļŦāļĨāļēāļĒ Bus

Middleware āļ„āļĢāļ­āļšāļ„āļĨāļļāļĄāļ—āļļāļāļāļēāļĢ dispatch āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ āđ€āļžāļīāđˆāļĄ cross-cutting concern āļ•āđˆāļēāļ‡āđ† stack middleware āđƒāļ™āļ•āļąāļ§āļˆāļąāļ”āļāļēāļĢ validation, Doctrine transaction āđāļĨāļ° routing

yaml
# config/packages/messenger.yaml
framework:
    messenger:
        default_bus: command.bus
        buses:
            command.bus:
                middleware:
                    - validation
                    - doctrine_transaction
            query.bus:
                middleware:
                    - validation
            event.bus:
                default_middleware:
                    allow_no_handlers: true
                middleware:
                    - validation

āļāļēāļĢāļāļģāļŦāļ™āļ”āļ„āđˆāļēāļ™āļĩāđ‰āļ™āļģāļĢāļđāļ›āđāļšāļš CQRS (Command Query Responsibility Segregation) āļĄāļēāđƒāļŠāđ‰ Command āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđāļ›āļĨāļ‡ state āļ āļēāļĒāđƒāļ™ Doctrine transaction Query āļ­āđˆāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļĒāđˆāļēāļ‡āđ€āļ”āļĩāļĒāļ§ Event āļ­āļ™āļļāļāļēāļ•āđƒāļŦāđ‰āđ„āļĄāđˆāļĄāļĩ handler āđ€āļĨāļĒāļāđ‡āđ„āļ”āđ‰ āļ—āļģāđƒāļŦāđ‰āļŠāļēāļĄāļēāļĢāļ–āđƒāļŠāđ‰āļĢāļđāļ›āđāļšāļš pub/sub āļ—āļĩāđˆ listener āļŠāļēāļĄāļēāļĢāļ–āđ€āļžāļīāđˆāļĄāđ€āļ‚āđ‰āļēāļĄāļēāđ„āļ”āđ‰āļ­āļĒāđˆāļēāļ‡āļ­āļīāļŠāļĢāļ°

āļžāļĢāđ‰āļ­āļĄāļ—āļĩāđˆāļˆāļ°āļžāļīāļŠāļīāļ•āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ Symfony āđāļĨāđ‰āļ§āļŦāļĢāļ·āļ­āļĒāļąāļ‡āļ„āļĢāļąāļš?

āļāļķāļāļāļ™āļ”āđ‰āļ§āļĒāļ•āļąāļ§āļˆāļģāļĨāļ­āļ‡āđāļšāļšāđ‚āļ•āđ‰āļ•āļ­āļš, flashcards āđāļĨāļ°āđāļšāļšāļ—āļ”āļŠāļ­āļšāđ€āļ—āļ„āļ™āļīāļ„āļ„āļĢāļąāļš

Middleware āļ›āđ‰āļ­āļ‡āļāļąāļ™āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģāđƒāļ™ Symfony 7.3

āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģāļŠāļīāđ‰āļ™āđ€āļ›āļĨāļ·āļ­āļ‡āļ—āļĢāļąāļžāļĒāļēāļāļĢāđāļĨāļ°āļ­āļēāļˆāļāđˆāļ­āđƒāļŦāđ‰āđ€āļāļīāļ”āļœāļĨāļ‚āđ‰āļēāļ‡āđ€āļ„āļĩāļĒāļ‡ āđ€āļŠāđˆāļ™ āđ€āļĢāļĩāļĒāļāđ€āļāđ‡āļšāđ€āļ‡āļīāļ™āļĨāļđāļāļ„āđ‰āļēāļŠāļ­āļ‡āļ„āļĢāļąāđ‰āļ‡ Symfony 7.3 āđ€āļ›āļīāļ”āļ•āļąāļ§ DeduplicateMiddleware āđ€āļžāļ·āđˆāļ­āļ‚āđ‰āļēāļĄāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāđ€āļŦāļĄāļ·āļ­āļ™āļāļąāļ™āļ‹āļķāđˆāļ‡āļ­āļĒāļđāđˆāđƒāļ™āļ„āļīāļ§āđāļĨāđ‰āļ§āđ‚āļ”āļĒāļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī

src/Message/SendWelcomeEmail.phpphp
namespace App\Message;

use Symfony\Component\Messenger\Stamp\DeduplicateStamp;

final readonly class SendWelcomeEmail
{
    public function __construct(
        public int $userId,
    ) {}
}
php
// Dispatch āļžāļĢāđ‰āļ­āļĄāļāļēāļĢāļ›āđ‰āļ­āļ‡āļāļąāļ™āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģ
use Symfony\Component\Messenger\Stamp\DeduplicateStamp;

$this->bus->dispatch(
    new SendWelcomeEmail(userId: 42),
    [new DeduplicateStamp(id: 'welcome-email-42')],
);

DeduplicateStamp āļĢāļąāļšāļ•āļąāļ§āļĢāļ°āļšāļļ lock resource āļŦāļēāļāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāļĄāļĩ ID āđ€āļ”āļĩāļĒāļ§āļāļąāļ™āļ­āļĒāļđāđˆāđƒāļ™āļŠāļ–āļēāļ™āļ° pending āļ­āļĒāļđāđˆāđāļĨāđ‰āļ§ āļāļēāļĢ dispatch āđƒāļŦāļĄāđˆāļˆāļ°āļ–āļđāļāļ‚āđ‰āļēāļĄāđ„āļ›āđ‚āļ”āļĒāđ„āļĄāđˆāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ āļŸāļĩāđ€āļˆāļ­āļĢāđŒāļ™āļĩāđ‰āļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•āđŒ Lock āļĢāđˆāļ§āļĄāļāļąāļš store āļ—āļĩāđˆ serialize āđ„āļ”āđ‰ (Redis, Memcached āļŦāļĢāļ·āļ­āļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ)

āļāļĨāļĒāļļāļ—āļ˜āđŒ Retry āđāļĨāļ° Failure Transport

āđ€āļĄāļ·āđˆāļ­ handler āđ‚āļĒāļ™ exception, Messenger āļˆāļ°āļĨāļ­āļ‡āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ‹āđ‰āļģāļ•āļēāļĄāļāļĨāļĒāļļāļ—āļ˜āđŒ retry āļ‚āļ­āļ‡ transport āļŦāļĨāļąāļ‡āļˆāļēāļāļŦāļĄāļ”āļˆāļģāļ™āļ§āļ™āļ„āļĢāļąāđ‰āļ‡āļ—āļĩāđˆāļāļģāļŦāļ™āļ” āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļˆāļ°āļ–āļđāļāļĒāđ‰āļēāļĒāđ„āļ›āļĒāļąāļ‡ failure transport

src/MessageHandler/PaymentHandler.phpphp
namespace App\MessageHandler;

use App\Message\ProcessPayment;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Messenger\Exception\RecoverableMessageHandlingException;

#[AsMessageHandler]
final class PaymentHandler
{
    public function __invoke(ProcessPayment $message): void
    {
        try {
            $this->gateway->charge($message->amount, $message->token);
        } catch (GatewayTimeoutException $e) {
            // āļāļđāđ‰āļ„āļ·āļ™āđ„āļ”āđ‰: āļĨāļ­āļ‡āđƒāļŦāļĄāđˆāļ”āđ‰āļ§āļĒ backoff
            throw new RecoverableMessageHandlingException(
                'Payment gateway timeout, retrying',
                previous: $e,
            );
        } catch (InvalidCardException $e) {
            // āļāļđāđ‰āļ„āļ·āļ™āđ„āļĄāđˆāđ„āļ”āđ‰: āļŠāđˆāļ‡āđ„āļ› failure transport āļ—āļąāļ™āļ—āļĩ
            throw new UnrecoverableMessageHandlingException(
                'Invalid card, no retry',
                previous: $e,
            );
        }
    }
}

RecoverableMessageHandlingException āđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰āļāļĨāļĒāļļāļ—āļ˜āđŒ retry āļŠāđˆāļ§āļ™ UnrecoverableMessageHandlingException āļ‚āđ‰āļēāļĄāļāļēāļĢ retry āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđāļĨāļ°āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ•āļĢāļ‡āđ„āļ›āļĒāļąāļ‡ failure transport āļāļēāļĢāđāļĒāļāđāļĒāļ°āļ™āļĩāđ‰āļŠāđˆāļ§āļĒāđ„āļĄāđˆāđƒāļŦāđ‰āđ€āļŠāļĩāļĒāļˆāļģāļ™āļ§āļ™āļ„āļĢāļąāđ‰āļ‡ retry āļāļąāļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāļĨāđ‰āļĄāđ€āļŦāļĨāļ§āļ­āļĒāđˆāļēāļ‡āļ–āļēāļ§āļĢ

bash
# āļ•āļĢāļ§āļˆāļŠāļ­āļšāđāļĨāļ°āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāļĨāđ‰āļĄāđ€āļŦāļĨāļ§
php bin/console messenger:failed:show
php bin/console messenger:failed:show 20 --transport=failed

# āļĨāļ­āļ‡āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāļĢāļ°āļšāļļāļ­āļĩāļāļ„āļĢāļąāđ‰āļ‡
php bin/console messenger:failed:retry 20 30

# āļāļĢāļ­āļ‡āđāļĨāļ°āļĨāļšāļ•āļēāļĄāļ„āļĨāļēāļŠ (Symfony 7.3+)
php bin/console messenger:failed:remove --class-filter="App\Message\CleanupTempFiles"
Handler āļ—āļĩāđˆāđ€āļ›āđ‡āļ™ Idempotent

āļāļĨāđ„āļāļāļēāļĢ retry āļŦāļĄāļēāļĒāļ„āļ§āļēāļĄāļ§āđˆāļē handler āļ­āļēāļˆāļ–āļđāļāđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰āļŦāļĨāļēāļĒāļ„āļĢāļąāđ‰āļ‡āļŠāļģāļŦāļĢāļąāļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđ€āļ”āļĩāļĒāļ§āļāļąāļ™ āļ—āļļāļ handler āļ„āļ§āļĢāļ­āļ­āļāđāļšāļšāđƒāļŦāđ‰āđ€āļ›āđ‡āļ™ idempotent: āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ§āđˆāļēāļ‡āļēāļ™āđ€āļŠāļĢāđ‡āļˆāđāļĨāđ‰āļ§āļŦāļĢāļ·āļ­āđ„āļĄāđˆāļāđˆāļ­āļ™āļ—āļģāļ‹āđ‰āļģ āđƒāļŠāđ‰ unique constraint āđƒāļ™āļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĢāļ·āļ­ flag āļŠāļ–āļēāļ™āļ°āđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ‹āđ‰āļģ

Doctrine Keepalive āđāļĨāļ°āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāđƒāļŠāđ‰āđ€āļ§āļĨāļēāļ™āļēāļ™

Handler āļ—āļĩāđˆāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđ€āļ›āđ‡āļ™āđ€āļ§āļĨāļēāļ™āļēāļ™āđ€āļŠāļĩāđˆāļĒāļ‡āļ—āļĩāđˆāļˆāļ°āļ–āļđāļāļŠāđˆāļ‡āļ‹āđ‰āļģāđ€āļĄāļ·āđˆāļ­ visibility timeout āļ‚āļ­āļ‡ transport āļŦāļĄāļ”āļ­āļēāļĒāļļ Symfony 7.2 āđ€āļ›āļīāļ”āļ•āļąāļ§ keepalive āļŠāļģāļŦāļĢāļąāļš Redis, SQS āđāļĨāļ° Beanstalkd āļŠāđˆāļ§āļ™ Symfony 7.3 āļ‚āļĒāļēāļĒāļŸāļĩāđ€āļˆāļ­āļĢāđŒāļ™āļĩāđ‰āđ„āļ›āļĒāļąāļ‡ transport Doctrine

bash
# āđ€āļ›āļīāļ” keepalive āđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļŠāđˆāļ‡āļ‹āđ‰āļģāļĢāļ°āļŦāļ§āđˆāļēāļ‡āļāļēāļĢāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ—āļĩāđˆāđƒāļŠāđ‰āđ€āļ§āļĨāļēāļ™āļēāļ™
php bin/console messenger:consume async --keepalive

flag --keepalive āļˆāļ°āļ­āļąāļ›āđ€āļ”āļ• timestamp delivered_at āđƒāļ™āļ•āļēāļĢāļēāļ‡ transport āļ‚āļ­āļ‡ Doctrine āđ€āļ›āđ‡āļ™āļĢāļ°āļĒāļ° āđ€āļžāļ·āđˆāļ­āđāļˆāđ‰āļ‡āļ§āđˆāļē worker āļĒāļąāļ‡āļ„āļ‡āļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ­āļĒāļđāđˆ āļŦāļēāļāđ„āļĄāđˆāđƒāļŠāđ‰ flag āļ™āļĩāđ‰ āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ™āļēāļ™āļāļ§āđˆāļē timeout āļ‚āļ­āļ‡ transport (āļ„āđˆāļēāđ€āļĢāļīāđˆāļĄāļ•āđ‰āļ™ 5 āļ™āļēāļ—āļĩ) āļˆāļ°āļ–āļđāļ worker āļ­āļ·āđˆāļ™āļ™āļģāđ„āļ›āļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨ āļ—āļģāđƒāļŦāđ‰āđ€āļāļīāļ”āļāļēāļĢāļ—āļģāļ‡āļēāļ™āļ‹āđ‰āļģāļ‹āđ‰āļ­āļ™

Attribute #[AsMessage] āļŠāļģāļŦāļĢāļąāļš Routing āđāļšāļšāļ›āļĢāļ°āļāļēāļĻ

Symfony 7.2 āđ€āļ›āļīāļ”āļ•āļąāļ§ attribute #[AsMessage] āļ‹āļķāđˆāļ‡āļĒāđ‰āļēāļĒāļāļēāļĢāļāļģāļŦāļ™āļ” transport routing āļˆāļēāļ YAML āđ„āļ›āļĒāļąāļ‡āļ„āļĨāļēāļŠ message āđ‚āļ”āļĒāļ•āļĢāļ‡

src/Message/GenerateReport.phpphp
namespace App\Message;

use Symfony\Component\Messenger\Attribute\AsMessage;

#[AsMessage(transport: 'async_priority_low')]
final readonly class GenerateReport
{
    public function __construct(
        public int $reportId,
        public string $format = 'pdf',
    ) {}
}

āļ§āļīāļ˜āļĩāļ™āļĩāđ‰āđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āļāļģāļŦāļ™āļ”āļŠāđˆāļ§āļ™ routing āđƒāļ™ messenger.yaml āļŠāļģāļŦāļĢāļąāļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ™āļąāđ‰āļ™āļ­āļĩāļāļ•āđˆāļ­āđ„āļ› Transport āļ–āļđāļāļ›āļĢāļ°āļāļēāļĻāļ—āļĩāđˆāļ•āđ‰āļ™āļ—āļēāļ‡ āļ—āļģāđƒāļŦāđ‰ codebase āļ­āļ˜āļīāļšāļēāļĒāļ•āļąāļ§āđ€āļ­āļ‡āđ„āļ”āđ‰āļŠāļąāļ”āđ€āļˆāļ™ āļ—āļąāđ‰āļ‡āļŠāļ­āļ‡āļ§āļīāļ˜āļĩ (routing YAML āđāļĨāļ° attribute) āļŠāļēāļĄāļēāļĢāļ–āđƒāļŠāđ‰āļĢāđˆāļ§āļĄāļāļąāļ™āđ„āļ”āđ‰ āđ‚āļ”āļĒ attribute āļˆāļ°āļĄāļĩāļĨāļģāļ”āļąāļšāļ„āļ§āļēāļĄāļŠāļģāļ„āļąāļāļŠāļđāļ‡āļāļ§āđˆāļē

Streaming AMQP Transport āļŠāļģāļŦāļĢāļąāļšāļ„āļīāļ§ Throughput āļŠāļđāļ‡

Transport AMQP āđāļšāļšāļ”āļąāđ‰āļ‡āđ€āļ”āļīāļĄāđƒāļŠāđ‰ polling (get()) āđ€āļžāļ·āđˆāļ­āļ”āļķāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ āļ‹āļķāđˆāļ‡āļŠāļĢāđ‰āļēāļ‡āļ āļēāļĢāļ°āļ—āļĩāđˆāđ„āļĄāđˆāļˆāļģāđ€āļ›āđ‡āļ™āļšāļ™ RabbitMQ āļŠāđˆāļ§āļ™ streaming AMQP transport āļ—āļĩāđˆāđ€āļ›āļīāļ”āļ•āļąāļ§āđƒāļ™āļ›āļĩ 2025 āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđ€āļ›āđ‡āļ™āđ‚āļĄāđ€āļ”āļĨ push (consume()) āļ‹āļķāđˆāļ‡āļĨāļ”āļ„āļ§āļēāļĄāļŦāļ™āđˆāļ§āļ‡āđāļĨāļ°āļāļēāļĢāđƒāļŠāđ‰āļ—āļĢāļąāļžāļĒāļēāļāļĢ

yaml
# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            streaming:
                dsn: 'amqp-lib://guest:guest@localhost:5672/%2f/messages'
                options:
                    exchange:
                        name: app_events
                        type: topic
                    queues:
                        order_events:
                            binding_keys: ['order.*']

āļ„āļ§āļēāļĄāđāļ•āļāļ•āđˆāļēāļ‡āļŦāļĨāļąāļāļˆāļēāļ transport AMQP āđ€āļĢāļīāđˆāļĄāļ•āđ‰āļ™: āđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰ C extension (āđƒāļŠāđ‰ php-amqplib), āļāļēāļĢāļŠāđˆāļ‡āđāļšāļš streaming āļœāđˆāļēāļ™āļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­ TCP āļ—āļĩāđˆāļ„āļ‡āļ­āļĒāļđāđˆāļĒāļēāļ§āļ™āļēāļ™ āđāļĨāļ°āļĢāļ­āļ‡āļĢāļąāļš topic exchange āļžāļĢāđ‰āļ­āļĄ routing binding key āđāļšāļš native Transport āļ™āļĩāđ‰āļŠāļēāļĄāļēāļĢāļ–āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļŦāļĨāļēāļĒāļžāļąāļ™āļĢāļēāļĒāļāļēāļĢāļ•āđˆāļ­āļ§āļīāļ™āļēāļ—āļĩāļ”āđ‰āļ§āļĒ CPU overhead āļ—āļĩāđˆāļ™āđ‰āļ­āļĒāļĄāļēāļ

āļŠāļĢāļļāļ›

  • āļŠāđˆāļ‡ ID āđāļšāļš scalar āđƒāļ™āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ āđ„āļĄāđˆāđƒāļŠāđˆ entity āļ‚āļ­āļ‡ Doctrine; āļ”āļķāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļĨāđˆāļēāļŠāļļāļ”āđƒāļ™ handler āđ€āļžāļ·āđˆāļ­āļŦāļĨāļĩāļāđ€āļĨāļĩāđˆāļĒāļ‡āļ›āļąāļāļŦāļē serialization āđāļĨāļ° state āļ—āļĩāđˆāļĨāđ‰āļēāļŠāļĄāļąāļĒ
  • āđāļšāđˆāļ‡ transport āļ•āļēāļĄāļĨāļģāļ”āļąāļšāļ„āļ§āļēāļĄāļŠāļģāļ„āļąāļāđāļĨāļ°āļĢāļ°āļ”āļąāļšāļ§āļīāļāļĪāļ•; āđāļ•āđˆāļĨāļ° transport āļĄāļĩāļāļĨāļĒāļļāļ—āļ˜āđŒ retry āđāļĨāļ° pool worker āļ‚āļ­āļ‡āļ•āļąāļ§āđ€āļ­āļ‡
  • āđƒāļŠāđ‰ RecoverableMessageHandlingException āđāļĨāļ° UnrecoverableMessageHandlingException āđ€āļžāļ·āđˆāļ­āļ„āļ§āļšāļ„āļļāļĄāļžāļĪāļ•āļīāļāļĢāļĢāļĄ retry āļ­āļĒāđˆāļēāļ‡āļŠāļąāļ”āđ€āļˆāļ™
  • āđ€āļ›āļīāļ” --keepalive āļšāļ™ worker transport Doctrine āđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļŠāđˆāļ‡āļ‹āđ‰āļģāļ‚āļ­āļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāđƒāļŠāđ‰āđ€āļ§āļĨāļēāļ™āļēāļ™
  • āđƒāļŠāđ‰ DeduplicateStamp āļāļąāļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļĩāđˆāļāļēāļĢāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļ‹āđ‰āļģāļāđˆāļ­āđƒāļŦāđ‰āđ€āļāļīāļ”āļœāļĨāļ‚āđ‰āļēāļ‡āđ€āļ„āļĩāļĒāļ‡ (āļāļēāļĢāļŠāļģāļĢāļ°āđ€āļ‡āļīāļ™, āļ­āļĩāđ€āļĄāļĨ, āļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™)
  • āļ™āļģ CQRS āļĄāļēāđƒāļŠāđ‰āļ”āđ‰āļ§āļĒāļŦāļĨāļēāļĒ bus: command bus āļŠāļģāļŦāļĢāļąāļš mutation āļžāļĢāđ‰āļ­āļĄ Doctrine transaction, query bus āļŠāļģāļŦāļĢāļąāļšāļ­āđˆāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ, event bus āļŠāļģāļŦāļĢāļąāļš pub/sub
  • āđƒāļŠāđ‰ Supervisor āļŦāļĢāļ·āļ­ systemd āđƒāļ™ production āļžāļĢāđ‰āļ­āļĄ flag --memory-limit, --time-limit āđāļĨāļ° --limit āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļ§āļ‡āļˆāļĢāļŠāļĩāļ§āļīāļ• worker
  • āļžāļīāļˆāļēāļĢāļ“āļē streaming AMQP transport āļŠāļģāļŦāļĢāļąāļšāļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒ throughput āļŠāļđāļ‡āļ—āļĩāđˆāļ•āđ‰āļ­āļ‡āļāļēāļĢāļ„āļ§āļēāļĄāļŦāļ™āđˆāļ§āļ‡āļ•āđˆāļģāļāļ§āđˆāļēāļĄāļīāļĨāļĨāļīāļ§āļīāļ™āļēāļ—āļĩ

āđ€āļĢāļīāđˆāļĄāļāļķāļāļ‹āđ‰āļ­āļĄāđ€āļĨāļĒ!

āļ—āļ”āļŠāļ­āļšāļ„āļ§āļēāļĄāļĢāļđāđ‰āļ‚āļ­āļ‡āļ„āļļāļ“āļ”āđ‰āļ§āļĒāļ•āļąāļ§āļˆāļģāļĨāļ­āļ‡āļŠāļąāļĄāļ āļēāļĐāļ“āđŒāđāļĨāļ°āđāļšāļšāļ—āļ”āļŠāļ­āļšāđ€āļ—āļ„āļ™āļīāļ„āļ„āļĢāļąāļš

āđāļ—āđ‡āļ

#symfony
#messenger
#queue
#worker
#async
#php
#interview

āđāļŠāļĢāđŒ

āļšāļ—āļ„āļ§āļēāļĄāļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡

āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ Symfony āđāļĨāļ° PHP - āļ„āļđāđˆāļĄāļ·āļ­āļ‰āļšāļąāļšāļŠāļĄāļšāļđāļĢāļ“āđŒ

āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ Symfony: 25 āļ­āļąāļ™āļ”āļąāļšāđāļĢāļāđƒāļ™āļ›āļĩ 2026

25 āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ Symfony āļ—āļĩāđˆāļ–āļđāļāļ–āļēāļĄāļšāđˆāļ­āļĒāļ—āļĩāđˆāļŠāļļāļ” āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄ, Doctrine ORM, āļšāļĢāļīāļāļēāļĢ, āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ, āļŸāļ­āļĢāđŒāļĄāđāļĨāļ°āļāļēāļĢāļ—āļ”āļŠāļ­āļš āļžāļĢāđ‰āļ­āļĄāļ„āļģāļ•āļ­āļšāļĨāļ°āđ€āļ­āļĩāļĒāļ”āđāļĨāļ°āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡āđ‚āļ„āđ‰āļ”

Symfony Security Voters Firewalls

āļĢāļ°āļšāļšāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ Symfony āļ›āļĩ 2026: Voters, Firewalls āđāļĨāļ°āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒāļ‡āļēāļ™āđ€āļ—āļ„āļ™āļīāļ„

āļ„āļđāđˆāļĄāļ·āļ­āđ€āļŠāļīāļ‡āļĨāļķāļāļĢāļ°āļšāļšāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ Symfony: firewalls, voters, IsGranted attribute, āļāļĨāļĒāļļāļ—āļ˜āđŒāļāļēāļĢāļ•āļąāļ”āļŠāļīāļ™āđƒāļˆ, āļāļēāļĢ debug āļœāđˆāļēāļ™ Twig āđƒāļ™ Symfony 7.4 āđāļĨāļ°āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒāļ‡āļēāļ™āļŠāļģāļŦāļĢāļąāļšāļ™āļąāļāļžāļąāļ’āļ™āļē PHP

Symfony Live Components āđāļĨāļ° UX 3.0 āļšāļ—āļŠāđˆāļ§āļĒāļŠāļ­āļ™

Symfony Live Components āđāļĨāļ° UX 3.0: āđāļ­āļ›āļžāļĨāļīāđ€āļ„āļŠāļąāļ™āđāļšāļš Reactive āđ‚āļ”āļĒāđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰ JavaScript āđƒāļ™āļ›āļĩ 2026

Symfony Live Components āļŠāļĢāđ‰āļēāļ‡āļ­āļīāļ™āđ€āļ—āļ­āļĢāđŒāđ€āļŸāļ‹āđāļšāļš reactive āļ”āđ‰āļ§āļĒ PHP āđāļĨāļ° Twig āđ‚āļ”āļĒāđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰ JavaScript āļšāļ—āļŠāđˆāļ§āļĒāļŠāļ­āļ™āđ€āļāļĩāđˆāļĒāļ§āļāļąāļš LiveProp, LiveAction, form āđāļĨāļ° deferred loading