Envoyer des emails avec Mailer sous Symfony 6

Voici ici comment envoyer des emails sous Symfony 6 avec le composant Mailer. Les composants Mailer et Mime de Symfony forment un système puissant pour la création et l’envoi d’e-mails – avec prise en charge des messages multipartites, intégration de Twig, inlining CSS, pièces jointes et bien plus encore. Installez-les avec :

composer require symfony/mailer

Configuration du transport

Les courriels sont délivrés via un « transport ». Par défaut, vous pouvez envoyer des e-mails via SMTP en configurant le DSN dans votre fichier .env (les paramètres user, pass et port sont facultatifs) :

.env

MAILER_DSN=smtp://user:pass@smtp.example.com:port
# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'

Attention : Si le nom d’utilisateur, le mot de passe ou l’hôte contiennent un caractère considéré comme spécial dans un URI (tel que +, @, $, #, /, :, *, !), vous devez les encoder. Consultez la RFC 3986 pour la liste complète des caractères réservés ou utilisez la fonction urlencode pour les coder.

Utilisation des transports intégrés

DSN protocolExampleDescription
smtpsmtp://user:pass@smtp.example.com:25Mailer uses an SMTP server to send emails
sendmailsendmail://defaultMailer uses the local sendmail binary to send emails
nativenative://defaultMailer uses the sendmail binary and options configured in the sendmail_path setting of php.ini. On Windows hosts, Mailer fallbacks to smtp and smtp_port php.ini settings when sendmail_path is not configured.

Utilisation d’un transport tiers

Au lieu d’utiliser votre propre serveur SMTP ou votre binaire sendmail, vous pouvez envoyer des e-mails via un fournisseur tiers. Mailer en supporte plusieurs – installez celui que vous voulez :

ServiceInstall with
Amazon SEScomposer require symfony/amazon-mailer
Gmailcomposer require symfony/google-mailer
MailChimpcomposer require symfony/mailchimp-mailer
Mailguncomposer require symfony/mailgun-mailer
Mailjetcomposer require symfony/mailjet-mailer
Postmarkcomposer require symfony/postmark-mailer
SendGridcomposer require symfony/sendgrid-mailer
Sendinbluecomposer require symfony/sendinblue-mailer
OhMySMTPcomposer require symfony/oh-my-smtp-mailer

Chaque bibliothèque comprend une recette Symfony Flex qui ajoutera un exemple de configuration à votre fichier .env. Par exemple, supposons que vous souhaitiez utiliser SendGrid. Tout d’abord, installez-le :

composer require symfony/sendgrid-mailer

Vous avez maintenant une nouvelle ligne dans votre fichier .env que vous pouvez décommenter :

# .env
MAILER_DSN=sendgrid://KEY@default

Le MAILER_DSN n’est pas une adresse réelle : il s’agit d’un format pratique qui décharge le mailer de la plupart des tâches de configuration. Le schéma sendgrid active le fournisseur SendGrid que vous venez d’installer, qui sait tout sur la façon de livrer les messages via SendGrid. La seule partie que vous devez modifier est le caractère générique KEY.

Chaque fournisseur possède différentes variables d’environnement que le Mailer utilise pour configurer le protocole réel, l’adresse et l’authentification pour la livraison. Certains ont également des options qui peuvent être configurées avec des paramètres de requête à la fin du MAILER_DSN – comme ?region= pour Amazon SES ou Mailgun. Certains fournisseurs prennent en charge l’envoi via http, api ou smtp. Symfony choisit le meilleur transport disponible, mais vous pouvez forcer l’utilisation d’un seul :

# .env
# force to use SMTP instead of HTTP (which is the default)
MAILER_DSN=sendgrid+smtp://$SENDGRID_KEY@default

Ce tableau présente la liste complète des formats DSN disponibles pour chaque fournisseur tiers :

ProviderSMTPHTTPAPI
Amazon SESses+smtp://USERNAME:PASSWORD@defaultses+https://ACCESS_KEY:SECRET_KEY@defaultses+api://ACCESS_KEY:SECRET_KEY@default
Google Gmailgmail+smtp://USERNAME:PASSWORD@defaultn/an/a
Mailchimp Mandrillmandrill+smtp://USERNAME:PASSWORD@defaultmandrill+https://KEY@defaultmandrill+api://KEY@default
Mailgunmailgun+smtp://USERNAME:PASSWORD@defaultmailgun+https://KEY:DOMAIN@defaultmailgun+api://KEY:DOMAIN@default
Mailjetmailjet+smtp://ACCESS_KEY:SECRET_KEY@defaultn/amailjet+api://ACCESS_KEY:SECRET_KEY@default
Postmarkpostmark+smtp://ID@defaultn/apostmark+api://KEY@default
Sendgridsendgrid+smtp://KEY@defaultn/asendgrid+api://KEY@default
Sendinbluesendinblue+smtp://USERNAME:PASSWORD@defaultn/asendinblue+api://KEY@default
OhMySMTPohmysmtp+smtp://API_TOKEN@defaultn/aohmysmtp+api://API_TOKEN@default

Créer et envoyer des messages

Pour envoyer un email, obtenez une instance de Mailer en tapant MailerInterface et créez un objet Email :

// src/Controller/MailerController.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;

class MailerController extends AbstractController
{
    /**
     * @Route("/email")
     */
    public function sendEmail(MailerInterface $mailer): Response
    {
        $email = (new Email())
            ->from('hello@example.com')
            ->to('you@example.com')
            //->cc('cc@example.com')
            //->bcc('bcc@example.com')
            //->replyTo('fabien@example.com')
            //->priority(Email::PRIORITY_HIGH)
            ->subject('Time for Symfony Mailer!')
            ->text('Sending emails is fun again!')
            ->html('<p>See Twig integration for better HTML integration!</p>');

        $mailer->send($email);

        // ...
    }
}

C’est tout ! Le message sera envoyé via le transport que vous avez configuré.

Adresses électroniques

Toutes les méthodes qui requièrent des adresses électroniques (from(), to(), etc.) acceptent à la fois des chaînes de caractères et des objets adresse :

// ...
use Symfony\Component\Mime\Address;

$email = (new Email())
    // email address as a simple string
    ->from('fabien@example.com')

    // email address as an object
    ->from(new Address('fabien@example.com'))

    // defining the email address and name as an object
    // (email clients will display the name)
    ->from(new Address('fabien@example.com', 'Fabien'))

    // defining the email address and name as a string
    // (the format must match: 'Name <email@example.com>')
    ->from(Address::create('Fabien Potencier <fabien@example.com>'))

    // ...
;

Note : Au lieu d’appeler ->from() à chaque fois que vous créez un nouvel e-mail, vous pouvez configurer les e-mails de manière globale afin de définir le même e-mail From pour tous les messages.

Utilisez les méthodes addTo(), addCc() ou addBcc() pour ajouter d’autres adresses :

$email = (new Email())
    ->to('foo@example.com')
    ->addTo('bar@example.com')
    ->cc('cc@example.com')
    ->addCc('cc2@example.com')

    // ...
;

Vous pouvez également transmettre plusieurs adresses à chaque méthode :

$toAddresses = ['foo@example.com', new Address('bar@example.com')];

$email = (new Email())
    ->to(...$toAddresses)
    ->cc('cc1@example.com', 'cc2@example.com')

    // ...
;

En-têtes de message

Les messages comprennent un certain nombre de champs d’en-tête pour décrire leur contenu. Symfony définit automatiquement tous les en-têtes requis, mais vous pouvez également définir vos propres en-têtes. Il existe différents types d’en-têtes (en-tête Id, en-tête Mailbox, en-tête Date, etc.) mais la plupart du temps, vous définirez des en-têtes de texte :

$email = (new Email())
    ->getHeaders()
        // this header tells auto-repliers ("email holiday mode") to not
        // reply to this message because it's an automated email
        ->addTextHeader('X-Auto-Response-Suppress', 'OOF, DR, RN, NRN, AutoReply')

    // ...
;

Contenu des messages

Le texte et le contenu HTML des messages électroniques peuvent être des chaînes (généralement le résultat du rendu d’un modèle) ou des ressources PHP :

$email = (new Email())
    // ...
    // simple contents defined as a string
    ->text('Lorem ipsum...')
    ->html('<p>Lorem ipsum...</p>')

    // attach a file stream
    ->text(fopen('/path/to/emails/user_signup.txt', 'r'))
    ->html(fopen('/path/to/emails/user_signup.html', 'r'))
;

Note : Vous pouvez également utiliser des modèles Twig pour rendre le contenu HTML et texte. Lisez la section Twig : HTML & CSS plus loin dans cet article pour en savoir plus.

Joindre des fichiers

Utilisez la méthode attachFromPath() pour joindre des fichiers qui existent sur votre système de fichiers :

$email = (new Email())
    // ...
    ->attachFromPath('/path/to/documents/terms-of-use.pdf')
    // optionally you can tell email clients to display a custom name for the file
    ->attachFromPath('/path/to/documents/privacy.pdf', 'Privacy Policy')
    // optionally you can provide an explicit MIME type (otherwise it's guessed)
    ->attachFromPath('/path/to/documents/contract.doc', 'Contract', 'application/msword')
;

Vous pouvez également utiliser la méthode attach() pour joindre le contenu d’un flux :

$email = (new Email())
    // ...
    ->attach(fopen('/path/to/documents/contract.doc', 'r'))
;