Vous devez envoyer des emails depuis votre application Symfony et vous ne savez pas par où commencer ? Le composant Mailer vous semble compliqué à configurer ? Vous voulez une méthode simple qui fonctionne à tous les coups ?
Cet article est un guide complet qui vous montre pas à pas comment faire. Nous allons voir ensemble l’installation, la configuration et l’envoi de vos premiers emails. C’est un guide complet pour maîtriser Symfony Mailer, à jour pour Symfony 6 et 7.
Prérequis et Installation du Composant Mailer
Avant de coder, il y a quelques vérifications à faire. C’est rapide et ça évite les problèmes plus tard. Assurez-vous d’avoir les éléments suivants sur votre machine de développement.
- PHP 8.1 ou une version plus récente.
- Composer, le gestionnaire de paquets pour PHP.
- Un projet Symfony déjà installé et fonctionnel.
Si tout est bon, la seule chose à faire est d’installer le composant Mailer. Ouvrez votre terminal, placez-vous à la racine de votre projet Symfony et tapez la commande suivante. Elle s’occupe de tout.
composer require symfony/mailer
Cette commande télécharge et installe le package `symfony/mailer`. Il s’agit du remplaçant moderne de l’ancien SwiftMailer. Il est mieux intégré à l’écosystème Symfony, notamment avec le composant Mime pour construire les messages.
Configurer le Transport d’Emails (le MAILER_DSN)
La configuration de Mailer se passe quasi entièrement dans un seul endroit : le fichier .env à la racine de votre projet. La variable qui nous intéresse est MAILER_DSN. DSN signifie « Data Source Name ». C’est une simple chaîne de caractères qui contient toutes les infos pour que Symfony sache comment envoyer l’email.
Il y a deux manières principales de configurer ce transport. Soit vous utilisez un serveur SMTP classique, soit vous passez par un service tiers spécialisé. On va voir les deux cas.
Option 1 : Configuration avec un serveur SMTP
C’est la méthode la plus courante, surtout pour commencer. Vous utilisez les identifiants d’un serveur de messagerie, comme celui de votre hébergeur, de votre entreprise ou même un compte SMTP Gmail.
Le format du MAILER_DSN pour un serveur SMTP ressemble à ça :
# .env
MAILER_DSN=smtp://user:pass@smtp.example.com:587
Il suffit de remplacer user, pass, smtp.example.com et le port (souvent 587, 465 ou 25) par vos propres informations. C’est tout. Votre application est prête à envoyer des emails via ce serveur.
💡 Pour Google Gmail : Si vous utilisez Gmail, il faut créer un « mot de passe d’application » dans les paramètres de sécurité de votre compte Google. N’utilisez pas votre mot de passe habituel, ça ne marchera pas.
Il existe plusieurs protocoles de transport. Voici un tableau qui résume les plus utiles pour vous aider à choisir.
| Protocole | Exemple de DSN | Cas d’usage |
|---|---|---|
smtp |
smtp://user:pass@smtp.example.com:587 |
Le plus courant. Pour se connecter à n’importe quel serveur SMTP distant. |
sendmail |
sendmail://default |
Pour les serveurs Linux/macOS où la commande sendmail est installée et configurée. |
native |
native://default |
Utilise la fonction mail() de PHP. Dépend de la configuration de sendmail_path dans votre php.ini. |
Envoyer un Email Simple : Le Code Étape par Étape
Maintenant que la configuration est prête, passons au code. Le processus est simple et se base sur deux éléments principaux : l’interface MailerInterface pour envoyer l’email, et la classe Email pour le construire.
Le plus simple est de travailler dans un contrôleur. Symfony, grâce à son système d’injection de dépendances, va nous fournir automatiquement une instance de MailerInterface. Il suffit de l’ajouter en argument de la méthode de votre contrôleur.
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Annotation\Route;
class MailController extends AbstractController
{
#[Route('/send-email')]
public function sendEmail(MailerInterface $mailer)
{
// Le code pour créer et envoyer l'email va ici
}
}
À l’intérieur de cette méthode, on va construire notre message. Pour ça, on crée une nouvelle instance de la classe Email. On utilise ensuite des méthodes très claires pour définir chaque partie du message.
from(): Définit l’adresse de l’expéditeur.to(): Définit le ou les destinataires.subject(): Le sujet de votre email.text(): Le contenu de l’email en format texte brut.html(): Le contenu en format HTML, plus riche.
Une fois l’objet $email préparé, la dernière étape est de l’envoyer avec la méthode $mailer->send($email). C’est cette ligne qui déclenche la communication avec le serveur SMTP que vous avez configuré dans le .env.
Voici un exemple de code complet et fonctionnel que vous pouvez tester directement dans votre application.
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;
class MailController extends AbstractController
{
#[Route('/send-email')]
public function sendEmail(MailerInterface $mailer): Response
{
$email = (new Email())
->from('contact@votresite.com')
->to('destinataire@exemple.com')
//->cc('cc@exemple.com')
//->bcc('bcc@exemple.com')
//->replyTo('reponse@votresite.com')
//->priority(Email::PRIORITY_HIGH)
->subject('Sujet de votre email de test')
->text('Ceci est le contenu en texte brut.')
->html('<p>Ceci est le contenu au format <strong>HTML</strong>.</p>');
try {
$mailer->send($email);
return new Response('Email envoyé avec succès !');
} catch (\Symfony\Component\Mailer\Exception\TransportExceptionInterface $e) {
// Gérer l'exception si l'email n'a pas pu être envoyé
return new Response('Erreur lors de l\'envoi de l\'email: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
}
Cas d’Usage Avancés avec Mailer
Envoyer un email simple, c’est bien. Mais souvent, on a besoin d’aller plus loin. Le composant Mailer de Symfony gère très bien des cas plus complexes comme les templates HTML ou l’ajout de pièces jointes.
Utiliser un Template Twig pour le corps de l’email
Écrire du HTML directement dans votre contrôleur, ce n’est pas très propre. La meilleure pratique est d’utiliser un template Twig, le moteur de templates de Symfony. Ça permet de séparer la logique du visuel.
Pour cela, on utilise une classe spéciale : TemplatedEmail. Elle fonctionne comme la classe Email, mais avec deux méthodes en plus : htmlTemplate() pour indiquer le chemin du fichier Twig, et context() pour passer des variables au template.
// Dans votre contrôleur
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
// ...
$email = (new TemplatedEmail())
->from('contact@votresite.com')
->to('destinataire@exemple.com')
->subject('Bienvenue sur notre site !')
// Chemin vers votre template Twig
->htmlTemplate('emails/signup.html.twig')
// Variables passées au template
->context([
'username' => 'John Doe',
'expiration_date' => new \DateTime('+7 days'),
]);
$mailer->send($email);
Votre template Twig (situé dans templates/emails/signup.html.twig) peut alors utiliser ces variables comme n’importe quel autre template.
Ajouter une pièce jointe
Ajouter un fichier en pièce jointe est aussi très simple. Il suffit d’utiliser la méthode attachFromPath() sur votre objet Email (ou TemplatedEmail). Le premier argument est le chemin vers le fichier sur votre serveur.
Vous pouvez aussi donner un nom personnalisé au fichier joint en deuxième argument. C’est pratique si le nom original n’est pas très parlant.
// ...
$email = (new Email())
->from('contact@votresite.com')
->to('destinataire@exemple.com')
->subject('Votre facture')
->html('<p>Veuillez trouver votre facture en pièce jointe.</p>')
// Attache un fichier depuis le disque
->attachFromPath('path/to/documents/facture-123.pdf');
$mailer->send($email);
Option 2 : Utiliser un Service Tiers pour une Meilleure Délivrabilité (Ex: Brevo)
Utiliser un serveur SMTP classique fonctionne, mais vous risquez d’avoir des problèmes de délivrabilité. Vos emails importants (confirmation d’inscription, réinitialisation de mot de passe) pourraient arriver dans le dossier spam de vos utilisateurs. Pour éviter ça, on utilise des services d’envoi d’emails transactionnels.
Ces services sont optimisés pour que vos messages arrivent bien en boîte de réception. Ils fournissent aussi des statistiques (ouverture, clics) et gèrent la réputation de vos adresses IP. L’un des plus connus est Brevo (anciennement Sendinblue).
L’avantage avec Symfony, c’est que passer à un service comme Brevo est très simple. La plupart des services officiellement supportés par Symfony nécessitent l’installation d’un transporteur via Composer, puis une simple mise à jour du MAILER_DSN. Votre code PHP, lui, ne change pas du tout.
Pour Brevo, par exemple, il vous faudra votre clé API. Le MAILER_DSN ressemblera à ça :
# .env
# Installez d'abord le transporteur : composer require symfony/brevo-mailer
MAILER_DSN=brevo+api://VOTRE_CLE_API@default
En changeant juste cette ligne, tous les emails envoyés via MailerInterface passeront par l’API de Brevo. C’est une solution robuste pour une application en production.
FAQ – Questions Fréquentes sur Symfony Mailer
Pour finir, voici quelques réponses aux questions que les développeurs se posent souvent lorsqu’ils utilisent le composant Mailer.
Comment tester les emails en local sans les envoyer ?
En développement, on ne veut pas envoyer de vrais emails. La solution est de configurer le MAILER_DSN pour qu’il pointe vers un serveur SMTP local qui intercepte les messages. Des outils comme MailHog ou MailCatcher sont parfaits pour ça. Votre DSN ressemblera à MAILER_DSN=smtp://localhost:1025.
Quelle est la différence avec l’ancien SwiftMailer ?
Symfony Mailer est le successeur de SwiftMailer. Il est plus moderne, mieux maintenu et s’intègre parfaitement avec les autres composants récents de Symfony, comme HttpClient. Si vous démarrez un projet, vous devez utiliser Mailer. Si vous êtes sur un ancien projet, la mise à jour est recommandée.
Comment gérer les erreurs d’envoi ?
L’envoi d’un email peut échouer (serveur indisponible, identifiants incorrects…). La méthode $mailer->send() peut lever une exception de type TransportExceptionInterface. Il est donc recommandé d’encadrer l’appel à send() dans un bloc try/catch pour gérer proprement ces erreurs et éviter que votre application ne plante.
