Skip to main content

Execute PHP code asynchronously with Symfony Messenger

The problem with synchronous execution

In traditional PHP, code executes synchronously: each instruction waits for the previous one to finish. This becomes problematic when an operation takes several seconds:

<?php 

public function sendNotification(User $user)
{
    $this->emailService->sendWelcomeEmail($user); // 4 secondes
    $this->smsService->sendConfirmation($user);   // 2 seconde
    $this->analytics->trackAction($user);         // 1 seconde
    
    // Total : 7 secondes d'attente pour l'utilisateur !
    return $this->render('confirmation.html.twig');
}

Result: The user waits in front of a loading screen.
To solve this problem, we can use “Symfony Messenger” to delay the execution of heavy scripts.

Setting up Symfony Messenger

Symfony Messenger is already well described in its official documentation. We will focus on the code part.
In the rest of this tutorial, you will find code snippets that you will need to adjust to your environment.

1- Create a Symfony Messenger handler

The handler is the class that contains the PHP code executed asynchronously. This is where you place the business logic that needs to run in the background.

<?php
namespace App\MessageHandler;

use App\Message\CheckMessageRead;
use App\Repository\MessageRepository;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Notifier\NotifierInterface;
Use Doctrine\ORM\EntityManagerInterface;

#[AsMessageHandler]
class CheckMessageReadHandler {

  public function __construct(private MessageRepository $messageRepository, private NotifierInterface $notifier, private EntityManagerInterface $em) {
  }

  public function __invoke(CheckMessageRead $messageCheck): void {
  	// votre logique metier.
  }
  
}

2- Create the data container

This class is the “package” that carries the data needed for asynchronous execution. It contains all the information the Handler will need to do its job. 

The Message is like an envelope containing instructions and data, while the Handler is the postal service that processes this envelope.

<?php

namespace App\Message;

class CheckMessageRead {

  public function __construct(public readonly int $messageId, public readonly string $routeName) {
  }

  public function getMessageId() {
    return $this->messageId;
  }
  
  public function getRouteName() {
    return $this->routeName;
  }
}

3- Create the data container

php bin/console debug:messenger
/etc/systemd/system/
php bin/console cache:clear --env=prod
php bin/console cache:clear --env=dev

Reconstruit les caches :

php bin/console cache:warmup 

php bin/console cache:warmup --env=prod

Profile picture for user admin Stephane K

Écrit le

Il y'a 23 hours
Modifié
Il y'a 23 hours
Loading ...
WhatsApp
Habeuk Support: +49 152 108 01753
Send