Envoyer des emails en PHP via SMTP ou API : PHPMailer, Symfony Mailer et la fonction mail()

On août 19, 2024
28min read
Viktoriia Ivanenko Technical Content Writer @ Mailtrap
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap

Si vous vous demandez comment envoyer des emails en PHP, vous n’êtes probablement pas le seul, car selon les rapports de W3Tech, même en 2024, 76,4 % de tous les sites web utilisent PHP.

Heureusement, vous êtes au bon endroit.

J’ai étudié le sujet pendant un certain temps et, dans cet article, je vais vous montrer les options les plus populaires pour envoyer des emails depuis PHP.

Les processus et les blocs de code que je vais vous montrer dans cet article sont compatibles avec la version 7 de PHP et les versions ultérieures.

Comment envoyer des emails avec PHPMailer

PHPMailer est l’une des bibliothèques d’envoi d’emails les plus populaires pour PHP, sinon la plus populaire. Elle est compatible avec la plupart des frameworks PHP (par exemple, Laravel, Symfony, etc.) et offre de nombreuses fonctionnalités telles que :

  • L’Authentification SMTP
  • Le Chiffrement Secure/MIME
  • La Prise en charge des protocoles TLS et SSL
  • Texte brut et contenu HTML
  • Des Modèles multipart/HTML complexe
  • Des Formats multiples, pièces jointes string et binaires
  • Du Support pour les images intégrées
  • Une Protection contre les attaques d’injection de header
  • Une Fonctionnalité pour la validation automatique des emails

Gardez en tête que PHPMailer ne possède pas d’envoi d’email intégré. Il peut envoyer des emails en utilisant la fonction mail() de PHP, mais je ne la recommande pas en raison des problèmes potentiels liés au spam et de la complexité du processus. Cependant, si vous souhaitez en savoir plus, n’hésitez pas à consulter notre article dédié à PHPMailer.

Idéalement, PHPMailer est utilisé avec un serveur SMTP externe, ce qui le rend fiable et sécurisé, faisant de lui un choix parfait pour l’envoi d’emails dans votre application PHP.

Maintenant, je vais décrire comment configurer PHPMailer pour n’importe quel fournisseur SMTP (par exemple, Mailtrap, SendGrid, Postmark, etc.) et plus tard, je vous montrerai comment l’utiliser avec Mailtrap SMTP pour voir comment cela fonctionne en pratique.

Tout d’abord, installez la bibliothèque via Composer, un gestionnaire de dépendances pour PHP recommandé par les créateurs de PHPMailer sur GitHub. Vous pouvez également suivre le manuel pour l’installation.

Une fois que vous avez installé Composer, ajoutez cette ligne à votre fichier composer.json :

"phpmailer/phpmailer": "^6.9"

ou exécutez la commande suivante :

composer require phpmailer/phpmailer

Alternativement, vous pouvez ajouter PHPMailer manuellement si vous ne souhaitez pas installer Composer, ce qui peut être utile dans un environnement de test. Pour ce faire, téléchargez les fichiers avec le code source de PHPMailer, copiez le contenu du dossier PHPMailer dans l’un des répertoires include_path spécifiés dans votre configuration PHP, et chargez chaque fichier de classe manuellement :

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'path/to/PHPMailer/src/Exception.php';
require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';

Maintenant, il ne reste plus qu’à ajouter les identifiants fournis par votre fournisseur de services SMTP (par exemple, nom d’utilisateur, mot de passe, port SMTP, etc.). Voici à quoi ils devraient ressembler :

$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = '1a2b3c4d5e6f7g';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;

Et voici comment cela se présente avec le code que vous pouvez utiliser pour envoyer un email :

<?php
// Start with PHPMailer class
use PHPMailer\PHPMailer\PHPMailer;
require_once './vendor/autoload.php';
// create a new object
$mail = new PHPMailer();
// configure an SMTP
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = '1a2b3c4d5e6f7g';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;

$mail->setFrom('confirmation@domaine-enregistré', 'Votre Hôtel');
$mail->addAddress('destinataire@gmail.com', 'Moi');
$mail->Subject = 'Merci d’avoir choisi Notre Hôtel !';
// Définir le HTML 
$mail->isHTML(TRUE);
$mail->Body = '<html>Bonjour, nous sommes heureux de <br>confirmer votre réservation.</br> Veuillez vérifier le document en pièce jointe.</html>';
$mail->AltBody = 'Bonjour, nous sommes heureux de confirmer votre réservation. Veuillez vérifier le document en pièce jointe.';
// ajouter une pièce joint 
// ajoutez simplement le '/path/to/file.pdf'
$attachmentPath = './confirmations/votreréservation.pdf';
if (file_exists($attachmentPath)) {
    $mail->addAttachment($attachmentPath, 'votreréservation.pdf');
}

// envoyer le message
if(!$mail->send()){
    echo 'Le message n'a pas pu être envoyé.';
    echo 'Erreur du Mailer : ' . $mail->ErrorInfo;
} else {
    echo 'Le message a été envoyé';
}

Comment envoyer des emails avec Symfony Mailer

Nous sommes en 2024, ce qui signifie que Pear::Mail et Swift Mailer sont maintenant devenus quelque peu obsolètes, ce qui fait de Symfony notre prochain choix évident pour envoyer des emails en PHP. C’est un framework super flexible et, grâce à ses nouveaux composants Mailer et Mime introduits dans la version Symfony 4.3, il offre les fonctionnalités suivantes :

  • L’Intégration de CSS inline
  • L’Intégration de modèles Twig
  • L’Ajout de Pièces jointes
  • La Signature et le chiffrement des messages
  • Une Intégration directe avec les fournisseurs de services de messagerie les plus populaires
  • L’Envoi d’emails asynchrone avec Symfony Messenger

Comme PHPMailer, Symfony vous permet d’envoyer des emails avec ou sans un service SMTP externe en utilisant Sendmail ou d’autres transports locaux. Bien que je ne sois pas fan du programme Sendmail car il est soumis à une plus grande surveillance des filtres anti-spam et nécessite beaucoup plus de maintenance, voici comment vous pouvez l’utiliser :

Tout d’abord, installez les composants Mime et Mailer, comme suit :

composer require symfony/mailer

Ensuite, exécutez le script suivant :

<?php

use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\Transport\SendmailTransport;
use Symfony\Component\Mime\Email;

require_once './vendor/autoload.php';

// Créez le transport Sendmail
$transport = new SendmailTransport();

// Créez le Mailer en utilisant votre Transport créé
$mailer = new Mailer($transport);

// Créez un nouvel email
$email = (new Email())
    ->from('allo@exemple.com')
    ->to('vous@exemple.com')
    ->subject('Utilisation de Sendmail avec Symfony !')
    ->text('Envoyer des emails avec Sendmail est facile !')
    ->html('<p>Voir l’intégration de Twig pour une meilleure intégration HTML !</p>');

// Envoyez l'email
$mailer->send($email);

D’autre part, si vous souhaitez envoyer vos emails de manière sécurisée et avec un taux de délivrabilité plus élevé, voici un code que vous pouvez utiliser avec Symfony et un SMTP externe :

<?php

use Symfony\Component\Mailer\Mailer; 
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; 
use Symfony\Component\Mime\Email;

require_once './vendor/autoload.php';


$transport = (new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport
('smtp.server.com', 587))
                ->setUsername('username')
                ->setPassword('password');

$mailer = new Mailer($transport); 

$email = (new Email())
            ->from('allo@enregistré.com')
            ->to('vous@exemple.com')
            ->subject('C’est l’heure de Symfony Mailer !')
            ->text('Envoyer des emails est de nouveau amusant !')
            ->html('<p>Voir l’intégration de Twig pour une meilleure intégration HTML !</p>');

$mailer->send($email);

Pour plus d’informations sur l’envoi d’emails avec Symfony Mailer, assurez-vous de consulter notre guide détaillé expliquant tout le processus et la documentation officielle pour la version actuelle.

PHP mail() function

La fonction mail() de PHP est une fonction intégrée pour envoyer des emails depuis PHP, mais elle présente certaines limitations et inconvénients qui la rendent moins populaire. Elle est souvent considérée comme étant “l’éléphant dans la pièce”.🐘

En effet, elle est sujette à des problèmes de délivrabilité car elle dépend de la configuration du serveur de messagerie local (par exemple, elle envoie des emails depuis votre serveur web), les emails peuvent donc être catégorisés comme étant du spam ou être rejettés par les fournisseurs de services de messagerie. Elle ne dispose pas de nombreuses fonctionnalités avancées comme le suivi des emails et, plus important encore, elle peut être vulnérable aux attaques par injection d’emails.

Ainsi, vous pouvez comprendre pourquoi je ne recommande pas la fonction mail(). Néanmoins, je vais vous montrer comment elle fonctionne à des fins explicatives.

La syntaxe de la fonction mail de PHP est assez simple :

<?php
mail($to,$subject,$message,[$headers],[$parameters]);
?>

Elle utilise les paramètres obligatoires suivants :

  • $to = l’email du destinataire de votre message. Le format de l’adresse email peut être utilisateur@exemple.com ou User <utilisateur@exemple.com>.En général, il doit être conforme à la RFC 2822. Ceci est obligatoire.
  • $subject = l’objet de votre message.
  • $message = le corps de votre message. Les lignes doivent être séparées par un retour chariot, CRLF, (\r\n). Chaque ligne ne doit pas dépasser 70 caractères.
  • $headers = l’en-tête from est obligatoire : il doit être spécifié, sinon vous recevrez un message d’erreur tel que Warning: mail(): “sendmail_from” non défini dans php.ini ou en-têteFrom: manquant.

Les en-têtes supplémentaires indiquent d’autres destinataires ou copies de votre message comme CC ou BCC. Ils peuvent être un tableau où la clé est un nom d’en-tête et la valeur est une valeur d’en-tête. Ou ils peuvent être une chaîne de caractères (string). Dans ce cas, les en-têtes doivent être séparés par un CRLF (\r\n).

  • $parameters = pour spécifier les paramètres supplémentaires définis dans le paramètre de configuration sendmail_path.

Voici comment vous pouvez envoyer un email en texte brut avec des en-têtes supplémentaires :

<?php
$to = "personne@exemple.com";
$subject = "Mon sujet";
$txt = "Hello world !";
$headers = "From: webmaster@exemple.com" . "\r\n" .
"CC: autrepersonne@exemple.com";

mail($to,$subject,$txt,$headers);
?>

Vous devez également vous rendre dans le dossier d’installation du fichier PHP et configurer les paramètres SMTP dans le fichier php.ini. Mais cela ne fonctionnera que pour localhost ou des solutions similaires à XAMPP, car, comme nous l’avons déjà mentionné, la fonction mail() de PHP ne prend pas en charge l’authentification SMTP et ne permet pas d’envoyer des messages via des serveurs externes.

Maintenant, si vous ne me croyez pas lorsque je vous dis que l’envoi d’emails HTML avec la fonction mail est plutôt complexe, voici à quoi ressemble généralement la partie message HTML :

// Message
$message = '
<html>
<head>
  <title>Rappel de demande de Révision</title>
</head>
<body>
  <p>Voici les cas nécessitant votre révision en décembre :</p>
  <table>
    <tr>
      <th>Titre du cas</th><th>Catégorie</th><th>Statut</th><th>Date limite</th>
    </tr>
    <tr>
      <td>Cas 1</td><td>Développement</td><td>en attente</td><td>20 déc.</td>
    </tr>
    <tr>
      <td>Cas 1</td><td>DevOps</td><td>en attente</td><td>21 déc.</td>
    </tr>
  </table>
</body>
</html>
';

Pour envoyer un email HTML, vous devez également définir l’en-tête Content-type :

$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

ou 

$headers['MIME-Version'] = 'MIME-Version: 1.0';
$headers['Content-type'] = text/html; charset=iso-8859-1';

Et si vous voulez envoyer votre message à plusieurs destinataires, spécifiez leurs adresses email dans le paramètre $to = en les séparant par une ou plusieurs virgules.

N’oubliez pas que lorsque vous envoyez des emails avec mail(), vous pouvez rencontrer de graves problèmes de délivrabilité d’emails. ❌ Les messages envoyés ne bénéficieront pas de la configuration SPF et DKIM sur votre domaine. Par conséquent, les messages seront probablement traités comme du spam par le MTA (Mail Transfer Agent) récepteur. Ainsi, la délivrabilité globale des messages envoyés via la fonction mail() de PHP n’est pas garantie. Enfin, vous ne recevrez pas de messages automatiques en cas d’échec de livraison.

Envoyer des emails en utilisant SMTP

Maintenant, je vais vous montrer comment utiliser PHPMailer avec le SMTP d’Email API/SMTP de Mailtrap, car il offre des taux de délivrabilité plus élevés que les autres options et est super facile à configurer.

La première chose à faire est de créer un compte et de vérifier votre domaine d’envoi d’emails comme décrit dans la vidéo ci-dessous :

Ensuite, trouvez les identifiants SMTP fournis par Mailtrap dans la section Sending Domains sous l’onglet SMTP/API Settings.

Une capture d'écran montrant les paramètres SMTP/API de l’Email API/SMTP de Mailtrap et le Transactional Stream.

Important : Choisissez le Transactional Stream pour l’instant ; je reviendrai sur le Bulk Stream plus tard dans l’article.

Maintenant, tout ce que vous avez à faire est d’utiliser le script suivant pour envoyer un email en texte brut et d’y insérer vos identifiants :

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php'; // Ajustez en fonction de votre méthode d'installation

$mail = new PHPMailer(true); // Activez les exceptions

// Configuration SMTP
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io'; // Votre serveur SMTP
$mail->SMTPAuth = true;
$mail->Username = 'your_username'; // Votre nom d'utilisateur Mailtrap
$mail->Password = 'your_password'; // Votre mot de passe Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 587;

// Paramètres de l'expéditeur et du destinataire
$mail->setFrom('de@exemple.com', 'Nom de l’Expéditeur');
$mail->addAddress('destinataire@exemple.com', 'Nom du Destinataire');

// Envoi d'un email en texte brut
$mail->isHTML(false); // Définir le format de l'email en texte brut
$mail->Subject = 'Votre sujet ici';
$mail->Body    = 'Ceci est le corps du message en texte brut';

// Envoyer l'email
if(!$mail->send()){
    echo 'Le message n'a pas pu être envoyé. Erreur du Mailer : ' . $mail->ErrorInfo;
} else {
    echo 'Le message a été envoyé';
}

Assurez-vous que la méthode isHTML soit définie sur false si vous souhaitez envoyer des emails en texte brut.

Envoyer des emails HTML

Plongez dans la personnalisation des emails HTML en PHP en consultant notre article dédié.

Pour envoyer un message HTML de base avec PHPMailer, nous devons simplement nous assurer que la propriété isHTML est définie sur (true) et nous pouvons l’envoyer comme suit :

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/composer/vendor/autoload.php'; // Assurez-vous que le chemin est correct

$mail = new PHPMailer(true); // Passer `true` active les exceptions

try {
    $mail->isSMTP();
    $mail->Host = 'live.smtp.mailtrap.io';
    $mail->SMTPAuth = true;
    $mail->Username = 'insérez un nom d'utilisateur généré par Mailtrap'; // Votre nom d'utilisateur Mailtrap
    $mail->Password = 'insérez un mot de passe généré par Mailtrap'; // Votre mot de passe Mailtrap
    $mail->SMTPSecure = 'tls';
    $mail->Port = 587;

    $mail->setFrom('de@exemple.com', 'Nom Prénom');
    $mail->addReplyTo('aqui@exemple.com', 'John Doe'); // 
    $mail->addAddress('destinataire@exemple.com', 'Nom du Destinataire'); // Ajouter un destinataire

    $mail->isHTML(true); // Définir le format de l'email en HTML
    $mail->Subject = "Test PHPMailer SMTP";
    $mail->Body = '<h1>Envoyer un email HTML en utilisant SMTP en PHP</h1><p>Ceci est un test d\'email que j\'envoie en utilisant le serveur de messagerie SMTP avec PHPMailer.</p>'; // Exemple de corps HTML
    $mail->AltBody = 'Ceci est la version texte brut du contenu de l\'email';

    if(!$mail->send()){
        echo 'Le message n\'a pas pu être envoyé.';
        echo 'Erreur du Mailer :' . $mail->ErrorInfo;
    } else {
        echo 'Le message a été envoyé';
    }
} catch (Exception $e) {
    echo "Le message n'a pas pu être envoyé. Erreur du Mailer : {$mail->ErrorInfo}";
}

Envoyer des emails à plusieurs destinataires

Pour envoyer des emails à plusieurs destinataires, tout ce que vous avez à faire est d’appeler la méthode addAddress() pour chaque destinataire.

Voici un exemple de code pour envoyer un email HTML et en texte brut à plusieurs destinataires :

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/composer/vendor/autoload.php';

$mail = new PHPMailer(true); // Active les exceptions
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g'; // Votre nom d'utilisateur Mailtrap
$mail->Password = '1a2b3c4d5e6f7g'; // Votre mot de passe Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->SMTPKeepAlive = true; // Gardez la connexion SMTP ouverte après chaque email envoyé

$mail->setFrom('liste@exemple.com', 'Gestionnaire de Liste');
$mail->Subject = "Nouvelle liste de diffusion Mailtrap";

$users = [
  ['email' => 'max@exemple.com', 'name' => 'Max'],
  ['email' => 'bob@exemple.com', 'name' => 'Bob']
];

foreach ($users as $user) {
  $mail->addAddress($user['email'], $user['name']); // Ajoutez correctement l'email de chaque utilisateur
  $mail->Body = "<h2>Bonjour, {$user['name']}!</h2> <p>Comment ça va ?</p>";
  $mail->AltBody = "Bonjour, {$user['name']}! \nComment ça va ?";

  try {
      if ($mail->send()) {
          echo "Message envoyé à : {$user['email']}\n";
      } else {
          echo "Erreur du Mailer ({$user['email']}): {$mail->ErrorInfo}\n";
      }
  } catch (Exception $e) {
      echo "Erreur du Mailer ({$user['email']}): {$e->getMessage()}\n";
  }
  $mail->clearAddresses(); // Effacer les adresses pour la prochaine itération
}

$mail->smtpClose(); // Possibilité de fermer la connexion SMTP

Astuce :

  • Vous pouvez également utiliser addCC() et addBCC() pour ajouter des destinataires en copie carbone (CC) et copie carbone invisible (BCC) respectivement.

Envoyer des emails avec pièces jointes

Pour envoyer des pièces jointes avec PHPMailer, vous avez deux options :

  • Joindre un fichier à partir de votre système de fichiers

Avec cette option, vous devez enregistrer vos fichiers dans le même répertoire que le script.

Pour joindre un fichier, il vous suffit de spécifier son chemin. De plus, vous pouvez ajouter un nom de fichier, mais c’est facultatif car le script utilisera le nom réel de votre fichier :

$mail->addAttachment('path/to/facture1.pdf', 'facture1.pdf');

Ainsi, par exemple, lorsque vous appelez ce script, PHPMailer joindra le fichier situé à path/to/facture1.pdf à l’email. Le deuxième paramètre, facture1.pdf, est facultatif et spécifie le nom du fichier tel qu’il apparaîtra au destinataire. Si vous ne l’indiquez pas, PHPMailer utilisera le nom de fichier d’origine.

Si vous souhaitez ajouter un autre fichier, répétez la commande :

$mail->addAttachment('path/to/calculation1.xlsx', 'calculation1.xlsx');
  • Ajouter une pièce jointe sous forme de string

Cette méthode vous permet de joindre des données sans avoir à les enregistrer d’abord sous forme de fichier physique sur votre système de fichiers. Essentiellement, vous attachez les données stockées dans une variable. Par exemple, vous pouvez extraire un fichier d’une base de données, tel qu’un BLOB (Binary Large Object), sans avoir besoin de l’enregistrer en tant que fichier.

Pour ce faire, utilisez la commande addStringAttachment(), qui doit transmettre le contenu et le nom du fichier :

$mysql_data = $mysql_row['blob_data'];
$mail->addStringAttachment($mysql_data, 'db_data.db'); 

Voici un exemple d’ajout de données stockées sous forme de BLOB à partir d’une base de données MySQL.

Vous pouvez également utiliser une URL à distance, comme suit :

$mail->addStringAttachment(file_get_contents($url), 'monfichier.pdf');

Envoi d’emails avec une image intégrée

Pour envoyer un email avec une image intégrée, j’utilise des pièces jointes CID, comme suit :

$mail->addEmbeddedImage('path/to/fichier_image.jpg', 'image_cid');
$mail->isHTML(true);
$mail->Body = '<img src="cid:image_cid">';

Et voici un exemple complet d’extrait de code pour vous donner une meilleure idée :

<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'path/to/composer/vendor/autoload.php';

$mail = new PHPMailer(true); // Active les exceptions

$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'collez celui généré par Mailtrap';
$mail->Password = 'collez celui généré par Mailtrap';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;

$mail->setFrom('de@exemple.com', 'Nom Prénom');
$mail->addReplyTo('aqui@exemple.com', 'John Doe');
$mail->addAddress('destinataire@exemple.com', 'Nom du Destinataire'); // Spécifiez le destinataire

$mail->isHTML(true);
$mail->Subject = "PHPMailer SMTP test";
$mail->addEmbeddedImage('path/to/fichier_image.jpg', 'image_cid'); // Spécifiez le chemin de votre image et un CID
$mail->Body = '<img src="cid:image_cid"> Corps de l’email en HTML'; // Utilisez le CID comme attribut src dans votre balise img
$mail->AltBody = 'Ceci est la version texte brut du contenu de l\'email';

if(!$mail->send()){
    echo 'Le message n\'a pas pu être envoyé.';
    echo 'Erreur du Mailer : ' . $mail->ErrorInfo;
}else{
    echo 'Le message a été envoyé';
}

Envoi d’emails asynchrone

Bien que PHPMailer soit synchrone par nature et ne prenne pas en charge les opérations asynchrones comme Node.js par exemple, nous pouvons utiliser la fonction exec() pour appeler un script PHP qui envoie l’email en arrière-plan.

Pour que cette méthode fonctionne, vous devrez installer le CLI PHP (Interface de ligne de commande).

Voici le script sendEmail.php que vous pouvez utiliser :

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/vendor/autoload.php'; // Ajustez le chemin si nécessaire

$mail = new PHPMailer(true);

// SMTP Configuration
$mail->isSMTP();
$mail->Host = 'smtp.example.com'; // Spécifiez le SMTP principal et celui de secours
$mail->SMTPAuth = true; // Activez l'authentification SMTP
$mail->Username = 'utilisateur@exemple.com'; // Nom d'utilisateur  SMTP
$mail->Password = 'secret'; // Mot de passe SMTP
$mail->SMTPSecure = 'tls'; // Activez le chiffrement TLS, `ssl` est également accepté
$mail->Port = 587; // Port TCP pour se connecter

// Paramètres de l'email
$mail->setFrom('de@exemple.com', 'Mailer');
$mail->addAddress('destinataire@exemple.com', 'Nom du Destinataire'); // Ajouter un destinataire
$mail->isHTML(true); // Définir le format de l'email en HTML
$mail->Subject = 'Voici le sujet';
$mail->Body    = 'Ceci est le corps du message HTML <b>en gras !</b>';
$mail->AltBody = 'Ceci est le corps en texte brut pour les fournisseurs de service messagerie qui ne supportent pas le HTML';

try {
    $mail->send();
    echo 'Le message a été envoyé';
} catch (Exception $e) {
    echo "Le message n'a pas pu être envoyé. Erreur du Mailer : {$mail->ErrorInfo}";
}

Pour exécuter ce script, utilisez la commande suivante :

exec("php /Absolute/path/to/sendEmail.php > /dev/null &");

Notes:

  • Assurez-vous que le chemin vers l’exécutable CLI PHP (php) est correctement spécifié.
    • Dans certains cas et environnements, vous devrez peut-être utiliser le chemin complet vers le binaire CLI (par exemple, /usr/bin/php).
  • N’oubliez pas de vérifier la configuration PHP de votre serveur pour vous assurer que des fonctions comme exec() ne soient pas désactivées, car elles le sont souvent dans les environnements d’hébergement mutualisé pour des raisons de sécurité.
    • La directive qui contrôle cela est la directive disable_functions dans php.ini.

Comment envoyer des emails en masse

Jusqu’à présent, nous avons utilisé le Transactional Stream de Mailtrap, mais maintenant nous allons utiliser les identifiants Bulk Stream, qui nous permettent d’envoyer des emails à de nombreux destinataires simultanément.

Connectez-vous donc à votre compte Mailtrap et accédez à l’onglet SMTP Settings, où vous trouverez les identifiants Bulk Stream sur le côté droit de la fenêtre.

Une capture d'écran des identifiants SMTP du Bulk Stream de Mailtrap.

Ensuite, ajoutez ces identifiants dans le script suivant, que vous pouvez utiliser pour envoyer des emails en masse :

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php'; // Chemin vers le fichier autoload de Composer

$mail = new PHPMailer(true);

try {
    //Server settings
    $mail->isSMTP();
    $mail->Host       = 'bulk.smtp.mailtrap.io'; // Définissez le serveur SMTP à utiliser pour l'envoi
    $mail->SMTPAuth   = true;               // Activez l'authentification SMTP
    $mail->Username   = 'votre_nom_utilisateur_smtp'; // Nom d'utilisateur SMTP
    $mail->Password   = 'votre_mot_de_passe_smtp'; // Mot de passe SMTP
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Activez le chiffrement TLS
    $mail->Port       = 587; // Port TCP à utiliser

    // Adresse de l'expéditeur et de réponse
    $mail->setFrom('de@exemple.com', 'Mailer');
    $mail->addReplyTo('Répondrea@exemple.com', 'Mailer');

    // Contenu
    $mail->isHTML(true); // Définir le format de l'email en HTML
    
    // Liste des destinataires
    $recipients = [
        ['email' => 'personne1@exemple.com', 'name' => 'Personne Un'],
        ['email' => 'personne2@exemple.com', 'name' => 'Personne Deux'],
        //  Ajoutez d'autres destinataires si nécessaire
    ];

    foreach ($recipients as $recipient) {
        $mail->addAddress($recipient['email'], $recipient['name']); // Ajouter un destinataire

        // Personnaliser le message
        $mail->Subject = 'Voici le sujet';
        $mail->Body    = 'Ceci est le corps du message HTML <b>en gras !</b>';
        $mail->AltBody = 'Ceci est le corps en texte brut pour les fournisseurs de service de messagerie qui ne supportent pas le HTML';

        $mail->send();
        $mail->clearAddresses(); // Effacer les adresses pour la prochaine itération
    }

    echo 'Les messages ont été envoyés';
} catch (Exception $e) {
    echo "Le message n'a pas pu être envoyé. Erreur du Mailer : {$mail->ErrorInfo}";
}

De cette façon, nous pouvons envoyer des emails à plusieurs destinataires sans ouvrir et fermer la connexion SMTP pour chaque email. C’est plus efficace que, disons, créer une nouvelle instance PHPMailer pour chaque email.

Mais, si vous avez affaire à un volume important d’emails, vous pouvez utiliser un système de file d’attente de tâches comme RabbitMQ, Beanstalkd, Redis, etc.

Pour l’exemple, je vais vous montrer comment le faire avec Redis.

Tout d’abord, installons un client PHP pour Redis, predis/predis, via Composer en exécutant la commande suivante dans le répertoire racine du projet où se trouve votre fichier composer.json :

composer require predis/predis

Ensuite, nous aurons besoin d’un script de producteur de tâches qui ajoutera des tâches d’email à une liste Redis. Notez qu’ici, chaque tâche peut être une string JSON encodée avec toutes les données nécessaires pour envoyer un email :

require 'vendor/autoload.php';

use Predis\Client;

$redis = new Client();

while (true) {
    // Essaie de récupérer une tâche de la liste 'emailQueue', se bloque pendant 5 secondes maximum si elle est vide
    $job = $redis->brpop(['emailQueue'], 5);

    if ($job) {
        // Format de la tâche : [$listName, $jobData]
        $emailDataJson = $job[1];
        $emailData = json_decode($emailDataJson, true);

        // Traitez le emailData...
        // Envoyez l'email avec PHPMailer, enregistrez les succès/échecs, etc

        echo "Tâche traitée depuis emailQueue : " . $emailDataJson . "\n";
    } else {
        // Aucune tâche n'était disponible dans la file d'attente pendant la période de temporisation
        echo "En attente de tâches...\n";
    }
}

Enfin, créons un script de travail et assurons-nous que PHPMailer est configuré avec les identifiants Bulk Stream :

<?php
require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use Predis\Client;

// Initialiser le client Redis
$redis = new Client();

// Fonction log
function logError($message) {
    // Ajouter les erreurs à un fichier log
    file_put_contents('email_errors.log', $message . PHP_EOL, FILE_APPEND);
}

// Fonction d'envoi d'email, devient true en cas de succès ou false en cas d'échec
function sendEmail($emailData) {
    $mail = new PHPMailer(true);

    try {
        // Configuration SMTP
        $mail->isSMTP();
        $mail->Host       = 'bulk.smtp.mailtrap.io';
        $mail->SMTPAuth   = true;
        $mail->Username   = 'votre_nom_utilisateur_smtp';
        $mail->Password   = 'votre_mot_de_passe_smtp';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;

        // Destinataires
        $mail->setFrom('de@exemple.com', 'Mailer');
        $mail->addAddress($emailData['email']); // Destinataire

        // Contenu
        $mail->isHTML(true); // Format de l'email en HTML
        $mail->Subject = $emailData['subject'];
        $mail->Body    = $emailData['body'];

        $mail->send();
        return true;
    } catch (Exception $e) {
        // Enregistrer l'erreur spécifique
        logError("L'email n'a pas pu être envoyé à {$emailData['email']}. Erreur du Mailer : " . $mail->ErrorInfo);
        return false;
    }
}

// Politique de réessai
$maxRetries = 3; // Nombre maximum de tentatives de réessai pour un envoi d'email échoué
$retryDelay = 2; // Délai initial entre les tentatives de réessai en secondes

while ($emailDataJson = $redis->rpop('emailQueue')) {
    $emailData = json_decode($emailDataJson, true);
    $attempt = 0;

    while (!sendEmail($emailData) && $attempt < $maxRetries) {
        $attempt++;
        // Backoff exponentiel
        sleep($retryDelay * pow(2, $attempt - 1));
    }

    if ($attempt == $maxRetries) {
        // Log final pour les emails qui ont échoué après toutes les tentatives
        logError("Échec final : l'email n'a pas pu être envoyé à {$emailData['email']} après $maxRetries tentatives.");
    } else {
        echo "Email envoyé à {$emailData['email']}\n";
    }
}

Astuce : Si vous optez pour Redis, je vous recommande d’utiliser un gestionnaire de processus comme Supervisor, qui maintiendra le script de travail en cours d’exécution et le redémarrera automatiquement s’il se plante.

Envoyer des emails en utilisant une API

La meilleure façon d’envoyer des emails via une API est d’utiliser le SDK PHP officiel d’un fournisseur de services de messagerie, car PHPMailer n’est pas conçu dans ce but. Heureusement, nous pouvons compter sur l’Email API de Mailtrap puisqu’il propose un client PHP et permet d’intégrer facilement Mailtrap à votre application.

Pour commencer à envoyer des emails avec l’Email API/SMTP de Mailtrap, vous devez d’abord créer un compte puis ajouter et vérifier votre domaine.

Ensuite, continuez en installant le SDK PHP officiel de Mailtrap via Composer.

Vous pouvez utiliser l’une des commandes suivantes pour débuter :

# Avec le client http symfony (recommandé)
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7

# Ou avec le client http guzzle
composer require railsware/mailtrap-php guzzlehttp/guzzle php-http/guzzle7-adapter

Note : Comme le client API de Mailtrap utilise l’abstraction client PSR-18 et n’est donc pas couplé à une bibliothèque spécifique pour l’envoi de messages HTTP, cela vous permet de choisir le client HTTP que vous souhaitez utiliser.

Et pour envoyer un email en texte brut avec le SDK, utilisez simplement l’extrait de code ci-dessous :

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Your API token from here https://mailtrap.io/api-tokens
$apiKey = getenv('CLÉ_API_MAILTRAP');
$mailtrap = new MailtrapClient(new Config($apiKey));

$email = (new Email())
    ->from(new Address('example@votre-domaine-ici.com', 'Test Mailtrap'))
    ->replyTo(new Address('reponse@votre-domaine-ici.com'))
    ->to(new Address('email@exemple.com', 'Jon')) // Destinataire unique
    ->priority(Email::PRIORITY_HIGH)
    ->subject('Meilleures pratiques pour créer des emails HTML')
    ->text('Hey ! Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l\'emploi. Le guide de Mailtrap sur la création d\'emails HTML est en ligne sur notre blog');

// En-têtes
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domaine.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')); // Pareil qu’addTextHeader

// Variables personnalisées
$email->getHeaders()
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'));

// Catégorie (doit être unique)
$email->getHeaders()
    ->add(new CategoryHeader('Test d\'intégration'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // API d'envoi d'emails (réel)
    
    var_dump(ResponseHelper::toArray($response)); // corps (tableau)
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

Note:

  • Assurez-vous de copier et coller votre clé API dans le script, que vous pouvez trouver dans l’onglet SMTP/API Settings sous la section Sending Domains.

Envoyer des emails HTML

Pour envoyer des emails HTML, modifiez simplement le script pour les emails en texte brut en ajoutant la méthode ->html().

Dans l’exemple de code ci-dessous, je vais vous montrer comment envoyer un email HTML que vous pouvez envoyer à plusieurs destinataires et y joindre des fichiers :

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;
use Symfony\Component\Mime\Part\DataPart;

require __DIR__ . '/vendor/autoload.php';

// Votre jeton API est disponible ici https://mailtrap.io/api-tokens


$apiKey = “MAILTRAP_API_KEY”;
$mailtrap = new MailtrapClient(new Config($apiKey));

$email = (new Email())
    ->from(new Address('exemple@votre-domaine-ici.com', 'Test Mailtrap'))
    ->replyTo(new Address('reponse@yvotre-domaine-ici.com'))
    ->to(new Address('email@exemple.com', 'Jon'))
    ->priority(Email::PRIORITY_HIGH)
    ->cc('mailtrapqa@exemple.com')
    ->addCc('staging@exemple.com')
    ->bcc('mailtrapdev@exemple.com')
    ->subject('Meilleures pratiques pour créer des emails HTML')
    ->text('Hey ! Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l\'emploi. Le guide de Mailtrap sur la création d\'emails HTML est en ligne sur notre blog')
    ->html(
        '<html>
        <body>
        <p><br>Hey</br>
        Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l\'emploi.</p>
        <p><a href="https://mailtrap.io/blog/build-html-email/">Le guide de Mailtrap sur la création d\'emails HTML</a> est en ligne sur notre blog.</p>
        <img src="cid:logo">
        </body>
    </html>'
    )
    ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml');

// Ajouter une pièce jointe
$email->attachFromPath('/path/to/votre/fichier.pdf', 'Nomdufichier.pdf', 'application/pdf');

// En-têtes
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domaine.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')); // Pareil qu’addTextHeader

// Variables personnalisées
$email->getHeaders()
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'));

// Catégorie (doit être unique)
$email->getHeaders()
    ->add(new CategoryHeader('Test d\'intégration'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // API d'envoi d'emails (réel)
    
    var_dump(ResponseHelper::toArray($response)); // corps (tableau)
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

Envoyer des emails à plusieurs destinataires

Pour envoyer un email à plusieurs destinataires, ajoutez simplement les adresses aux champs to, cc, et bcc du code. La classe Email de Symfony, utilisée dans le script, permet d’ajouter plusieurs destinataires dans chacun des champs.

Voici un exemple de code que vous pouvez utiliser :

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Your API token from here https://mailtrap.io/api-tokens
$apiKey = getenv('CLÉ_API_MAILTRAP');
$mailtrap = new MailtrapClient(new Config($apiKey));

$email = (new Email())
    ->from(new Address('exemple@votre-domaine-ici.com', 'Test Mailtrap'))
    ->replyTo(new Address('reponse@votre-domaine-ici.com'))
    ->to(new Address('email@exemple.com', 'Jon'))
    ->priority(Email::PRIORITY_HIGH)
    ->cc('mailtrapqa@exemple.com')
    ->addCc('staging@exemple.com')
    ->bcc('mailtrapdev@exemple.com')
    ->subject('Meilleures pratiques pour créer des emails HTML')
    ->text('Hey ! Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l\'emploi. Le guide de Mailtrap sur la création d\'emails HTML est en ligne sur notre blog');

// Headers
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domaine.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')); // Pareil qu’addTextHeader

// Variables personnalisées
$email->getHeaders()
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'));

// Catégorie (doit être unique)
$email->getHeaders()
    ->add(new CategoryHeader('Integration Test'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // API d'envoi d'emails (réel)
    
    var_dump(ResponseHelper::toArray($response)); // corps (tableau)
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

Envoyer des emails avec des pièces jointes

Pour envoyer un email avec des pièces jointes, nous pouvons utiliser la méthode attachFromPath() fournie par la classe Email de Symfony Mime. Elle permet de joindre un fichier en spécifiant le chemin vers le fichier.

Vous pouvez utiliser le code suivant pour envoyer un email avec des pièces jointes :

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Votre jeton API est disponible ici https://mailtrap.io/api-tokens


$apiKey = “CLÉ_API_MAILTRAP”;
$mailtrap = new MailtrapClient(new Config($apiKey));

// Initialiser l'objet de l’email
$email = (new Email())
    ->from(new Address('exemple@votre-domaine-ici.com', 'Test Mailtrap'))
    ->replyTo(new Address('reepons@votre-domaine-ici.com'))
    ->to(new Address('email@exemple.com', 'Jon')) // Pour plusieurs destinataires, répétez cette ligne avec des adresses différentes
    ->priority(Email::PRIORITY_HIGH)
    ->subject('Meilleures pratiques pour créer des emails HTML')
    ->text("Hey ! Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l'emploi. Le guide de Mailtrap sur la création d'emails HTML est en ligne sur notre blog”);

// Joindre un fichier
$email->attachFromPath('/path/to/your/fichier.pdf', 'nomdufichier.pdf', 'application/pdf');

// En-têtes et Variables personnalisées comme défini précédemment
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domaine.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
    ->add(new CategoryHeader('Integration Test'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // Envoyer l'email via Mailtrap
    var_dump(ResponseHelper::toArray($response)); // Afficher la réponse
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

Envoi d’emails avec une image intégrée

L’envoi d’emails avec une image intégrée est également assez simple, car nous pouvons utiliser la méthode ->embed() dans l’objet Email. La méthode permet essentiellement d’inclure des images directement dans le corps HTML de l’email, qui peuvent être référencées par un Content-ID (CID).

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Votre jeton API est disponible ici https://mailtrap.io/api-tokens
$apiKey = getenv('CLÉ_API_MAILTRAP');
$mailtrap = new MailtrapClient(new Config($apiKey));

// Initialiser l'objet de l’email avec les détails nécessaires
$email = (new Email())
    ->from(new Address('exemple@votre-domaine-ici.com', 'Test Mailtrap'))
    ->replyTo(new Address('reponse@votre-domaine-ici.com'))
    ->to(new Address('email@exemple.com', 'Nom Destinataire'))
    ->subject('Email HTML avec image intégrée')
    ->html('<html><body>Voici une image intégrée : <img src="cid:unique-image-id"></body></html>');

// Intégrer l'image et lui attribuer un CID
$imagePath = '/path/to/votre/image.jpg'; // Assurez-vous d'utiliser le bon chemin vers votre fichier image
$email->embedFromPath($imagePath, 'unique-image-id');

// (Optionnel) Ajouter des configurations supplémentaires comme CC, BCC, partie texte, etc.

try {
    $response = $mailtrap->sending()->emails()->send($email); // Envoyer l'email via Mailtrap
    var_dump(ResponseHelper::toArray($response)); // Afficher la réponse
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

Astuce : N’oubliez pas de remplacer /path/to/votre/image.jpg par le chemin réel vers votre fichier image.

Envoi d’emails asynchrone

Pour envoyer des requêtes HTTP de manière asynchrone, vous pouvez utiliser les fonctions curl_multi de PHP.

La fonction curl_multi_init() fait partie de l’extension cURL, qui vous permet d’effectuer plusieurs requêtes HTTP simultanément, mais si cette extension n’est pas activée ou installée, vous ne pourrez pas l’utiliser, et il en va de même pour les autres fonctions de cURL.

Pour résoudre ce problème, vous devez activer l’extension cURL dans votre installation PHP. Voici les étapes à suivre pour différents systèmes d’exploitation :

sudo apt-get update
sudo apt-get install php-curl

Après l’installation, vous devrez peut-être activer manuellement l’extension en modifiant votre fichier php.ini, bien qu’elle soit généralement activée automatiquement. Si nécessaire, trouvez votre fichier php.ini (le chemin dépend de votre version de PHP et de votre configuration, un chemin courant pourrait être /etc/php/7.4/cli/php.ini pour PHP 7.4 CLI) et assurez-vous que la ligne extension=curl ne soit pas commentée (supprimez le point-virgule au début de la ligne s’il existe).

Vous devez redémarrer le serveur Apache.

sudo service apache2 restart

Voici un exemple de code sur la manière de procéder :

<?php

// Initialiser le multi handle de cURL
$multiCurl = curl_multi_init();

// Tableau pour suivre les handles de cURL individuels
$curlHandles = [];

// Exemple : Données d'email multiples (pour démonstration, envoi du même email à plusieurs destinataires)
$emailDatas = [
    [
        'from' => 'de@exemple.com',
        'to' => 'destinataire1@exemple.com',
        'subject' => 'Voici le sujet',
        'text' => 'Ceci est le corps du message en texte brut',
        'html' => '<p>Ceci est le corps du message en HTML</p>',
    ],
    [
        'from' => 'de@exemple.com',
        'to' => 'destinataire2@exemple.com',
        'subject' => 'Voici le sujet',
        'text' => 'Ceci est le corps du message en texte brut',
        'html' => '<p>Ceci est le corps du message en HTML</p>',
    ]
    // Ajoutez d'autres destinataires si nécessaire
];

foreach ($emailDatas as $emailData) {
    // Préparer le handle cURL pour chaque email
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.mailtrap.io/v1/messages'); // Utilisez le bon endpoint API
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($emailData));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer votre_jeton_api_mailtrap', //  Utilisez votre véritable jeton API de Mailtrap
    ]);

    // Ajouter le handle cURL au handle multi
    curl_multi_add_handle($multiCurl, $ch);
    $curlHandles[] = $ch; // Suivre les handles
}

// Exécuter le handle cURL multi
$active = null;
do {
    $mrc = curl_multi_exec($multiCurl, $active);
    if ($mrc != CURLM_OK) {
        // Gérer l'erreur cURL multi
        break;
    }
    // Attendre l'activité sur n'importe quelle connexion curl_multi
    if (curl_multi_select($multiCurl) == -1) {
        usleep(100);
    }
} while ($active);

// Lire et traiter les réponses
foreach ($curlHandles as $handle) {
    $response = curl_multi_getcontent($handle);
    // Traitez votre réponse ici. Vérifiez le code de statut HTTP, le corps de la réponse, etc.
    echo $response . PHP_EOL;

    // Supprimez et fermez le handle
    curl_multi_remove_handle($multiCurl, $handle);
    curl_close($handle);
}

// Fermer le handle cURL multi
curl_multi_close($multiCurl);

Comment envoyer des emails en masse

Si vous prévoyez d’envoyer un grand nombre d’emails en PHP avec l’Email API/SMTP de Mailtrap,, le mieux est d’utiliser un système de file d’attente de tâches.

Mais d’abord, nous devons configurer notre Bulk Stream. Accédez à l’onglet SMTP/API Settings dans votre compte Mailtrap et sélectionnez API dans la fenêtre Bulk Stream. Là, vous pouvez trouver l’hôte et le jeton API, que vous devez copier et coller dans votre script PHP.

Paramètres API Bulk Stream de Mailtrap

Avec ces identifiants Bulk Stream configurés comme ceci, vous pouvez utiliser pratiquement n’importe quel système de file d’attente de tâches, tel que RabbitMQ, Beanstalkd, etc. Pour les besoins de ce tutoriel, je vais vous montrer comment configurer Redis.

Si ce n’est pas déjà fait, ajoutez Redis à votre projet :

composer require predis/predis

Pour mettre une tâche en file d’attente dans Redis avec toutes les informations nécessaires, utilisez l’extrait de code PHP suivant :

require 'vendor/autoload.php';

$predis = new Predis\Client();

$emailData = [
    'from' => 'de@exemple.com',
    'to' => 'destinataire@exemple.com',
    'subject' => 'Votre sujet ici',
    'html' => '<p>Votre contenu HTML ici</p>',
    'text' => 'Votre texte brut ici',
    // Incluez toutes les autres données nécessaires pour l'email
];

// Mettre en file d'attente les données de l'email pour un traitement ultérieur
$predis->lpush('emailQueue', json_encode($emailData));

Enfin, utilisez ce script PHP qui surveille continuellement la file d’attente Redis pour de nouvelles tâches d’email, les retire de la file d’attente et les envoie via l’Email API/SMTP de Mailtrap :

require 'vendor/autoload.php';

$predis = new Predis\Client();
$mailtrapConfig = new Mailtrap\Config('your_mailtrap_api_key');
$mailtrapClient = new Mailtrap\MailtrapClient($mailtrapConfig);

while (true) {
    // Bloquer jusqu'à ce qu'une tâche d'email soit disponible
    $emailTask = $predis->brpop('emailQueue', 0);
    
    if ($emailTask) {
        $emailData = json_decode($emailTask[1], true); // $emailTask[1] contient les données de l'emaila
        
        // Envoyer l'email en utilisant l’Email API/SMTP de Mailtrap
        $email = (new Symfony\Component\Mime\Email())
            ->from(new Address($emailData['from']))
            ->to(new Address($emailData['to']))
            ->subject($emailData['subject'])
            ->html($emailData['html'])
            ->text($emailData['text']);
        
        try {
            $response = $mailtrapClient->sending()->emails()->send($email);
            echo "Email envoyé : ", var_dump($response), "\n";
        } catch (Exception $e) {
            echo "Échec de l'envoi de l'email : ", $e->getMessage(), "\n";
        }
    }
}

Et n’oubliez pas d’exécuter ce script pour qu’il fonctionne en arrière-plan ou en tant que tâche dans un gestionnaire de processus tel que Supervisor.

Tester les emails avant de les envoyer

Jusqu’à présent, j’ai décrit diverses façons d’envoyer des emails en PHP, mais comment savoir si votre fonctionnalité d’envoi d’emails fonctionne comme prévu ? Avec tout ce code en place, il est crucial de tester vos emails en PHP avant de les envoyer, quelle que soit la méthode d’envoi que vous choisissez.

Tester vos emails est la norme de l’industrie et une étape inextricable du cycle de l’Email API/SMTP. Heureusement, nous avons ce qu’il vous faut avec l’Email Testing de Mailtrap, la solution holistique.

Avec l’Email Testing de Mailtrap, vous pouvez vérifier, prévisualiser et résoudre les problèmes de vos emails avant de les envoyer. Essentiellement, vous pouvez inspecter le HTML/CSS de votre email et repérer facilement les lignes de code défectueuses pour les corriger/supprimer.

Vérification de l’HTML sur Mailtrap

Cette fonctionnalité est cruciale pour vérifier la compatibilité de vos conceptions HTML/CSS basées sur des modèles et les peaufiner à la perfection sans craindre d’envoyer réellement l’email.

Vous pouvez également partager votre processus de test avec vos membres d’équipe, créer de nouveaux projets, ajouter plusieurs projets à l’intérieur, et plus encore avec l’Email Testing de Mailtrap.

Projets de Mailtrap

Plus important encore, la configuration de l’Email Testing de Mailtrap est un véritable jeu d’enfant, car la solution peut facilement être intégrée soit via des identifiants SMTP, soit via le SDK PHP officiel.

SMTP

Pour tester vos emails avec un serveur SMTP fictif, il vous suffit de spécifier les identifiants SMTP de Mailtrap dans votre méthode de transport :

Host: sandbox.smtp.mailtrap.io
Port: 25 or 465 or 587 or 2525
Username: unique pour chaque boîte de réception Mailtrap
Password: unique pour chaque boîte de réception Mailtrap
TLS: Optionnel (STARTTLS sur tous les ports)

Vous pouvez également intégrer Mailtrap à diverses bibliothèques et frameworks PHP. Par exemple, voici un exemple d’intégration avec PHPMailer :

$phpmailer = new PHPMailer();
$phpmailer->isSMTP();
$phpmailer->Host = 'sandbox.smtp.mailtrap.io';
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 587;
$phpmailer->Username = '1a2b3c4d5e6f7g';
$phpmailer->Password = '1a2b3c4d5e6f7g';

Et voici à quoi ressemblerait votre MAILER_DSN si vous deviez intégrer Mailtrap avec le framework Symfony, par exemple :

MAILER_DSN=smtp://username:password@sandbox.smtp.mailtrap.io:587/?encryption=tls

Une fois que vous avez envoyé votre email de test, vous pouvez vérifier la boîte de réception virtuelle de Mailtrap après quelques instants, et vous devriez voir le message suivant :

Aperçu HTML de l’Email Testing de Mailtrap

API

Pour intégrer l’Email Testing de Mailtrap à votre application basée sur PHP, vous pouvez utiliser le code suivant :

?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/../vendor/autoload.php';


/**********************************************************************************************************************
 ******************************************* EMAIL TESTING ************************************************************
 **********************************************************************************************************************
 */

/**
 * Email Testing API
 *
 * POST https://sandbox.api.mailtrap.io/api/send/{inbox_id}
 */
try {
    // votre jeton API est disponible ici https://mailtrap.io/api-tokens
    $apiKey = getenv('MAILTRAP_API_KEY');
    $mailtrap = new MailtrapClient(new Config($apiKey));

    $email = (new Email())
        ->from(new Address('mailtrap@exemple.com', 'Test Mailtrap'))
        ->replyTo(new Address('reponse@exemple.com'))
        ->to(new Address('email@exemple.com', 'Jon'))
        ->cc('mailtrapqa@exemple.com')
        ->addCc('staging@exemple.com')
        ->bcc('mailtrapdev@exemple.com')
        ->subject('Meilleures pratiques pour créer des emails HTML')
        ->text('Hey ! Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l\'emploi. Le guide de Mailtrap sur la création d\'emails HTML est en ligne sur notre blog')
        ->html(
            '<html>
            <body>
            <p><br>Hey</br>
            Apprenez les bonnes pratiques pour créer des emails HTML et essayez des modèles prêts à l\'emploi.</p>
            <p><a href="https://mailtrap.io/blog/build-html-email/">Le guide de Mailtrap sur la création d\'emails HTML</a> est en ligne sur notre blog.</p>
            <img src="cid:logo">
            </body>
        </html>'
        )
        ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml')
        ->attachFromPath('README.md')
    ;

    // En-têtes
    $email->getHeaders()
        ->addTextHeader('X-Message-Source', '1alf.com')
        ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
    ;

    // Variables personnalisées
    $email->getHeaders()
        ->add(new CustomVariableHeader('user_id', '45982'))
        ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
    ;

    // Catégorie (doit être unique)
    $email->getHeaders()
        ->add(new CategoryHeader('Test d\'intégration'))
    ;

    // Paramètre obligatoire -> inbox_id
    $response = $mailtrap->sandbox()->emails()->send($email, 1000001); // <--- vous devez utiliser votre inbox_id ici (sinon vous obtiendrez 401)

    // afficher toutes les informations possibles de la réponse
    var_dump($response->getHeaders()); // en-têtes (tableau)
    var_dump($response->getStatusCode()); // code de statut (int)
    var_dump(ResponseHelper::toArray($response)); // corps (tableau)
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

Et bien sûr, n’oubliez pas de remplacer les valeurs de remplacement, telles que le jeton API et d’autres identifiants par les données réelles fournies par votre compte Mailtrap.

Pour plus d’informations sur l’Email Testing de Mailtrap, ses fonctionnalités et les différentes opérations qu’il vous permet d’effectuer (par exemple, Testing et QA Automation, testing des séquences automatisées, etc.), veuillez vous référer à la documentation officielle.

Conclusion

Et voilà, nous avons terminé notre tutoriel sur la manière d’envoyer des emails en PHP !

J’ai abordé les options d’envoi d’emails les plus populaires en PHP et décrit comment vous pouvez le faire avec un service de messagerie tiers comme Mailtrap, qui peut vous aider à économiser du temps, de l’argent et des efforts.

Si vous êtes intéressé par d’autres articles PHP, n’oubliez pas de consulter notre blog où vous pouvez lire d’autres articles liés à PHP, tels que :

Article by Viktoriia Ivanenko Technical Content Writer @ Mailtrap

Experienced content and marketing specialist: content creation for the blog and video channel, UX/UI copies, technical writing, app localizations, and SEO. Skilled in marketing strategies, video production and management, creating brand concepts, technical and marketing writing, and analytical skills. Strong information technology professional of 10+ years work experience with a background from The University of Edinburgh, UK and Clark University, USA.

Ivan Djuric, an author at Mailtrap
Article by Ivan Djuric Technical Content Writer @Mailtrap

I’m a Technical Content Writer with 5 years of background covering email-related topics in tight collaboration with software engineers and email marketers. I just love to research and share actionable insights with you about email sending, testing, deliverability improvements, and more. Happy to be your guide in the world of emails!