Pourquoi passer par SMTP pour envoyer un message ?

Utiliser le protocole SMTP pour envoyer des emails transactionnels dans vos projets PHP a plusieurs avantages. Le premier est de passer par une connexion sécurisée pour l’envoi du message. En effet, la fonction mail native de PHP n’utilise pas de connexion sécurisée donc les messages peuvent être interceptés sur le réseau. Ce n’est pas bien grave quand on envoie des messages de tests lors du développement. Second avantage, si on est développeur web sur macOS il est difficile d’envoyer un message en local ainsi via la librairie PHPMailer et une adresse mail on peut concevoir des applications PHP plus facilement.

La librairie PHPMailer est l’une des plus utilisées dans les applications PHP. Initialement créée en 2001 par Brent Matzelle, cette bibliothèque s’est beaucoup développée par la communauté. Elle est présente dans de nombreux projets open source comme WordPress, Drupal et de nombreuses autres solutions. En tant que développeur web il est difficile de ne pas utiliser cette librairie au lieu de la fonction native de PHP. Une autre solution consiste à utiliser des emails transactionnels en passant par une API comme Sendinblue ou MailerSend. Utiliser une API pour envoyer des messages permet aussi de séparer la partie graphique de la partie développement.

PHPMailer facilite l'envoi des emails transactionnels dans une application PHP
PHPMailer facilite l’envoi des emails transactionnels dans une application PHP

Configurer PHPMailer pour utiliser SMTP

Pour cet exemple il faut une adresse mail chez OVH ou un autre fournisseur. Attention quelques FAI bloquent les envois par SMTP sur certains serveurs pour éviter les spams. Une fois PHPMailer intégré au projet, nous reprendrons le code d’exemple de la documentation afin d’envoyer un message. Dans un premier temps on importe la librairie PHPMailer avec les classes requises pour l’envoi. Il faut aussi importer la classe Exception qui permet de lever et de récupérer le message d’erreur lors de l’utilisation de la librairies.

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

require 'PHPMailer-6.6.0/src/Exception.php';
require 'PHPMailer-6.6.0/src/PHPMailer.php';
require 'PHPMailer-6.6.0/src/SMTP.php';

$mail = new PHPMailer(true);

Ensuite on va créer un bout de code d’envoi avec la configuration adéquate pour utiliser SMTP dans une connexion chiffrée. Il est nécessaire d’appeler la méthode isSMTP afin d’initialiser PHPMailer au bon protocole puis de le configurer. Si on ne le fait pas cela appellera la fonction native mail du serveur PHP. Pour rappel chez OVH le nom du serveur est ssl0.ovh.net, le port 465 et le chiffrement SSL/TLS.

// Config
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->isSMTP();
$mail->Host       = 'ssl0.ovh.net';
$mail->SMTPAuth   = true;
$mail->Username   = 'contact@jagullo.fr';
$mail->Password   = '*******';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port       = 465;

// Header
$mail->setFrom('contact@jagullo.fr');
$mail->addAddress('test@test.fr');
$mail->addReplyTo('contact@jagullo.fr');

// Content
$mail->isHTML(true);
$mail->Subject = 'Here is an email test';
$mail->Body    = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

try {
    // Send
    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

Dans la variable Username on indique son adresse email et dans la variable Password son mot de passe. Pour définir le bon chiffrement, il faut appeler la variable SMTPSecure qui nécessite une constante de PHPMailer ENCRYPTION_SMTPS. Si on doit utiliser du STARTTLS on peut définir la constante ENCRYPTION_STARTTLS.

Résolution des problèmes

Il se peut que la connexion au serveur SMTP via SSL ne fonctionne pas en local sur certains systèmes comme Windows. On peut se référer à la documentation de PHPMailer pour tenter de résoudre quelques problèmes. En développement il est possible de forcer une connexion non sécurisée ce qui permet de réaliser des tests avant la mise en production.

$mail->SMTPOptions = [
    'ssl' => [
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true,
    ]
];

Plus de sécurité avec OAuth

On pourrait utiliser Gmail ou Microsoft comme serveur SMTP mais ces entreprises ont désactivé la prise en charge du protocole SMTP pour leur messagerie. Il est possible d’utiliser le protocole OAuth (Open Authorization) qui est un protocole libre pour sécuriser les authentifications à des services et des API en se basant sur un système de token. Dans sa version 6.6, PHPMailer facilite l’intégration de OAuth pour envoyer des emails avec plus de sécurité. Il existe de nombreuses ressources sur Internet qui traite de ce point et qui peut aussi faire l’objet d’un prochain tutoriel.

Alternative à PHPMailer

Il existe plusieurs alternatives à cette bibliothèque dans différents langages. En PHP il y a Symfony Mailer qui est la librairie par défaut du framework Symfony mais qui peut être utilisée indépendamment. D’ailleurs le framework Laravel utilise lui aussi Symfony Mailer pour l’envoi de message. Sur le serveur NodeJS on retrouve Nodemailer qui est une librairie open source pour envoyer un mail en pur JavaScript. Il existe aussi Emailjs en JavaScript qui implémente seulement le protocole SMTP. De nombreuses solutions open source sont disponibles suivant le langage de programmation que l’on utilise et le type de serveur.

Une autre possibilité d’envoyer un message, comme vu dans l’introduction, est de passer par la plateforme Sendinblue ou MailerSend. Ces services proposent d’envoyer un message en passant par une API. On réaliser un template de mail sur la plateforme avec des variables d’entrée puis on appelle l’API en PHP en renseignant les variables du template. Enfin on envoie l’email directement depuis le serveur ce qui permet de développer tout cela en local sans aucun souci. Un service d’email transactionnel permet d’avoir une meilleure délivrabilité et plus de sécurité pour son application. Enfin il est possible d’avoir des statistiques sur les messages d’envoi comme le taux de délivrabilité, les liens cliqués, etc.