Envoi de courriel
Présentation
L'envoi de courriels est une fonctionnalité courante dans de nombreuses applications web :
- Authentification à double facteur : Après la saisie de vos identifiants, un code de vérification est envoyé par email pour renforcer la sécurité de la connexion.
- Formulaire de contact : Les visiteurs peuvent remplir un formulaire sur votre site, et un courriel est envoyé à votre équipe pour traiter la demande.
- Notifications et alertes : Que ce soit pour confirmer une inscription, envoyer un reçu de paiement ou prévenir d'une activité suspecte, l'envoi d'emails permet de tenir les utilisateurs informés en temps réel.
Lorsqu'un courriel est envoyé, il est pris en charge par un serveur SMTP (Simple Mail Transfer Protocol), qui joue le rôle de bureau de poste. Ce serveur se connecte à Internet pour acheminer le message en recherchant le serveur SMTP du destinataire. Une fois transmis, le message est stocké sur le serveur du destinataire et pourra être récupéré via un protocole IMAP ou POP3.
Chaque courriel est composé de deux parties :
- Un corps, qui contient le message principal et éventuellement des pièces jointes.
- Des en-têtes, qui transportent des informations sur l'expéditeur, le destinataire, le sujet et d'autres métadonnées nécessaires à la transmission et à l'organisation du message. Les en-têtes précisent également le type de contenu du courriel, permettant d'indiquer le format du message et sa structure. De plus, un encodage de transmission est appliqué pour s'assurer que le message est correctement interprété par les serveurs et clients de messagerie, quel que soit le système utilisé.
Pour tester l'envoi de courriels pendant le développement, vous pouvez utiliser des environnements locaux comme Laragon ou d'autres outils de simulation SMTP. Ces solutions permettent de vérifier que vos emails sont correctement formatés et envoyés, sans avoir à utiliser un serveur de production, facilitant ainsi le développement et le débogage de votre application.
Pour des cas d'envoi complexes, il est recommandé d'utiliser des bibliothèques telles que PHPMailer ou Symfony Mailer, qui offrent une flexibilité et une sécurité accrues.
Test de l'Envoi de Courriels en Local
Avant de débuter avec l'envoi de courriels, vous devez disposer d'un environnement de travail local permettant de tester cette fonctionnalité.
Pour les utilisateurs de Laragon, cette fonctionnalité est intégrée nativement. Assurez-vous simplement qu'elle est activée dans les options. Pour cela, ouvrez l'interface de Laragon et vérifiez que l'option est bien cochée via : Menu > PHP > Intercepteur du courriel > Activé.
Si vous n'utilisez pas Laragon ou si vous souhaitez un outil plus avancé pour tester l'envoi de courriels tout en restant simple d'utilisation, vous pouvez installer MailHog.
MailHog
Installation de MailHog
- macOS et Linux : Rendez-vous sur la page principale du dépôt GitHub de MailHog et suivez les instructions d'installation adaptées à votre système d'exploitation.
- Windows : Rendez-vous sur la page des versions du dépôt GitHub de MailHog, puis téléchargez le fichier correspondant à votre architecture (AMD64 ou ARM64). Sous Windows, MailHog est une application portable, ce qui signifie qu'aucune installation n'est requise. Il suffit d'exécuter le fichier téléchargé pour lancer MailHog.
Configuraiton de Mailhog
Si vous utilisez déjà un outil de gestion locale des courriels, pensez à désactiver cette fonctionnalité pour éviter tout conflit de configuration. Par exemple, si vous l'utilisez avec Laragon, décochez l'option suivante : Menu > PHP > Intercepteur du courriel > Activé.
Une fois cela fait, configurez le fichier php.ini de la version de PHP que vous utilisez. Par exemple, si votre environnement de travail est géré avec Laragon, vous pouvez y accéder directement via l'interface : Menu > PHP > php.ini.
- macOS et Linux :
Si MailHog a été installé avec Homebrew et que vous souhaitez connaître son chemin, utilisez la commande suivante :SMTP = localhost smtp_port = 1025 sendmail_path = "/chemin/vers/mailhog sendmail"which mailhog - Windows :
SMTP = localhost smtp_port = 1025 sendmail_path = "C:\chemin\vers\MailHog.exe sendmail"
Relancez les services de votre serveur web et de PHP pour appliquer les modifications.
Utilisation de MailHog
- macOS :
- exécuter MailHog :
brew services start mailhog - arrêter MailHog :
brew services stop mailhog
- exécuter MailHog :
- Linux :
mailhog - Windows : Exécuter la version portable téléchargée depuis le dépôt GitHub. Par exemple, MailHog_windows_amd64.exe.
Il ne reste plus qu'à ouvrir MailHog dans votre navigateur en accédant à l'adresse suivante : http://localhost:8025. Une fois sur l'interface de MailHog, cliquer sur Connected en haut à gauche pour vous connecter au service.
Envoyer un Courriel
Pour l'envoi de courriel, il existe diverses bibliothèques très performantes qui vous faciliteront la vie. Cependant, pour le plaisir de s'arracher les cheveux, nous allons utiliser la fonction prédéfinie mail() :
mail(
string $destinataire,
string $sujet,
string $message,
array|string $entetes = [],
string $params_additionnels = ""
): bool
- $destinataire : L'adresse courriel du/des destinataire(s). Pour envoyer un même courriel à plusieurs destinataires, il faut séparer par des virgules les différentes adresses courriel de la chaîne de caractères.
- $sujet : Le sujet du courrier.
- $message : Le contenu du courrier.
- $entetes (optionnel) : Les en-têtes de courrier électronique sont utilisés pour acheminer, afficher et organiser les courriels, ainsi que pour permettre une communication efficace entre les serveurs de messagerie et les clients de messagerie.
- $params_additionnels (optionnel) : Des paramètres supplémentaires qui sont spécifiques au serveur de messagerie ou au programme de transfert SMTP.
Voici le code minimum requis pour envoyer un courriel :
<?php
$destinataire = "destinataire@exemple.com";
$sujet = "Sujet du courriel";
$message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac fermentum ex.";
mail($destinataire, $sujet, $message);
?>
L'envoi de courriel peut échouer pour diverses raisons, telles qu'une mauvaise configuration du serveur de messagerie ou des paramètres incorrects dans l'en-tête du courriel. Pour vérifier si l'envoi a réussi, vous pouvez utiliser la valeur de retour de la fonction mail(). Cette fonction retourne true si le courriel a été accepté pour une tentative d'envoi par le serveur de messagerie, ou false en cas d'échec.
<?php
$destinataire = "destinataire@exemple.com";
$sujet = "Sujet du courriel";
$message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac fermentum ex.";
// Tentative d'envoi du courriel :
if (mail($destinataire, $sujet, $message))
{
echo "Le courriel a été envoyé avec succès.";
}
else
{
echo "L'envoi du courriel a échoué.";
}
?>
Bien que la RFC 5322 autorise des lignes pouvant aller jusqu'à 998 caractères, il est courant de limiter leur longueur à environ 70 à 78 caractères pour améliorer la lisibilité, assurer la compatibilité avec les clients de messagerie anciens et éviter des problèmes potentiels lors de la transmission via certains serveurs SMTP.
<?php
$destinataire = "destinataire@exemple.com";
$sujet = "Sujet du courriel";
$message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac fermentum ex.";
// Limiter la longueur de chaque ligne à 70 caractères pour améliorer la lisibilité et la compatibilité,
// notamment avec l'encodage quoted-printable.
$message = wordwrap($message, 70, "\r\n");
if (mail($destinataire, $sujet, $message))
{
echo "Le courriel a été envoyé avec succès.";
}
else
{
echo "L'envoi du courriel a échoué.";
}
?>
Selon la norme SMTP (RFC 5321), une ligne contenant uniquement un point marque la fin du message. Si un saut de ligne généré par wordwrap() place un point en début de ligne, certains serveurs SMTP interrompront le message au premier point isolé, tronquant le contenu. Pour éviter cela, il faut échapper les points en début de ligne en ajoutant un deuxième point. Le serveur SMTP destinataire supprimera automatiquement ce point supplémentaire.
<?php
$destinataire = "destinataire@exemple.com";
$sujet = "Sujet du courriel";
$message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac fermentum ex.";
// Couper les lignes qui font plus de 70 caractères à l'aide de la fonction "wordwrap()".
$message = wordwrap($message, 70, "\r\n");
// Doubler tout point situé en début de ligne pour éviter que le serveur SMTP ne l'interprète comme
// une commande signalant la fin du message.
$message = str_replace("\n.", "\n..", $message);
if (mail($destinataire, $sujet, $message))
{
echo "Le courriel a été envoyé avec succès.";
}
else
{
echo "L'envoi du courriel a échoué.";
}
?>
Exercices - Part 01
Exo-envoi-de-courriel-01
- Objectif : Installer, configurer et tester MailHog, un outil permettant de simuler l'envoi de courriels en local.
- Instructions :
- Installez, configurez et exécutez MailHog en suivant les étapes du chapitre traitant de l'envoi de courriels en local.
- Créez un nouveau dossier nommé exo-envoi-de-courriel-01.
- Dans ce dossier, créez un fichier nommé index.php.
- Dans ce fichier, utilisez la fonction prédéfinie mail() pour tester l'envoi d'un courriel et sa réception avec MailHog. Ce courriel doit contenir :
- Un sujet. Par exemple : Mon premier courriel.
- Un destinataire. Par exemple : test@exemple.com.
- Un message. Par exemple : Ceci est un test d'envoi de courriel.
- Pour préparer le test de la réception de courriel, ouvrez MailHog dans votre navigateur à l'adresse suivante : http://localhost:8025.
- Vous pouvez maintenant envoyer le courriel. Pour cela, ouvrez le terminal de votre éditeur de code, assuez-vous d'être placé dans le dossier exo-envoi-de-courriel-01, puis exécutez le fichier index.php avec la commande suivante : php index.php.
- Retournez dans l'onglet de votre navigateur où MailHog est ouvert et vérifiez si le courriel a bien été reçu. Si rien n'apparaît, cliquez sur le bouton Refresh pour actualiser la boîte de réception.
Configuration des en-têtes
Les en-têtes de courriels sont des métadonnées qui accompagnent chaque message électronique. Ils permettent de spécifier diverses informations sur le courriel, telles que l'expéditeur, le sujet, la date et l'heure d'envoi, le type de contenu (texte brut ou HTML), le codage des caractères, et d'autres informations pertinentes pour le traitement et l'affichage du message par les clients de messagerie.
Lorsque vous utilisez la fonction mail() sans spécifier explicitement l'en-tête, les valeurs par défaut sont généralement définies par la configuration du serveur de messagerie (SMTP) que PHP utilise pour envoyer les courriels. Les en-têtes par défaut incluront au minimum un en-tête From avec l'adresse courriel de l'expéditeur, un en-tête Reply-To avec l'adresse courriel du destinataire et éventuellement un en-tête Date avec la date et l'heure de l'envoi du courriel.
Pour un meilleur contrôle sur la manière dont vos courriels sont traités et affichés par les clients de messagerie, vous avez la possibilité de spécifier les en-têtes de ceux-ci :
<?php
$expediteur = "info@service.com";
$destinataire = "destinataire@exemple.com";
$sujet = "Sujet du courriel";
// Préciser le fuseau horaire désiré.
date_default_timezone_set('Europe/Paris');
// Générer une date compatible (format RFC 5322) à partir du fuseau horaire configuré.
// Exemple : "Mon, 03 Feb 2025 14:30:00 +0100"
$date = date('r');
// Configuration simple de l'en-tête.
$entete = [
"From" => $expediteur,
"Date" => $date
];
// Le message du courriel.
$message = "Contenu du courriel...";
// Couper les lignes qui font plus de 70 caractères à l'aide de la fonction "wordwrap()".
$message = wordwrap($message, 70, "\r\n");
// Doubler tout point situé en début de ligne pour éviter que le serveur SMTP ne l'interprète comme
// une commande signalant la fin du message.
$message = str_replace("\n.", "\n..", $message);
// Tentative d'envoi du courriel :
if (mail($destinataire, $sujet, $message, $entete))
{
echo "Le courriel a été envoyé avec succès.";
}
else
{
echo "L'envoi du courriel a échoué.";
}
?>
Les en-têtes les plus couramment utilisés dans un courriel sont les suivants :
- From (Expéditeur) : Cet en-tête affiche l'adresse courriel (et éventuellement le nom) de l'expéditeur, ce qui permet au destinataire d'identifier qui envoie le message. Il facilite également la réponse en fournissant l'adresse de retour et contribue à la crédibilité du message, en aidant les filtres anti-spam à vérifier son authenticité :
<?php $expediteur = "Claudy Focan <claudy.focan@gmail.com>"; // Sans le nom : $expediteur = "claudy.focan@gmail.com"; $entete = ["From" => $expediteur]; ?> - Reply-To (Adresse de Réponse) : Cet en-tête indique l'adresse courriel (et éventuellement le nom) à laquelle les réponses au message doivent être envoyées. Il est particulièrement utile lorsque vous souhaitez que les réponses soient dirigées vers une adresse différente de celle qui apparaît dans le champ From :
<?php $expediteur = "info@service.com"; $adresseDeReponse = "contact@service.com"; $entete = [ "From" => $expediteur, "Reply-To" => $adresseDeReponse ]; ?> - Cc (Copie Carbone) : Cet en-tête permet d'ajouter des destinataires en copie carbone (CC) à votre courriel. Les destinataires CC reçoivent une copie du courriel, mais ils ne sont pas les destinataires principaux :
<?php $cc = "marc@exemple.com, sophier@exemple.com"; $entete = ["Cc" => $cc]; ?> - Bcc (Copie Carbone Invisible) : Cet en-tête est similaire à Cc, mais il permet d'ajouter des destinataires en copie carbone invisible (BCC). Les destinataires BCC reçoivent une copie du courriel, mais leur adresse n'est pas visible pour les autres destinataires :
<?php $bcc = "copiecachee@exemple.com"; $entete = ["Bcc" => $bcc]; ?> - MIME-Version (Version MIME) : Cet en-tête indique la version du standard MIME utilisée dans le message. MIME (Multipurpose Internet Mail Extensions) est une norme qui permet aux courriels d'envoyer non seulement du texte, mais aussi d'autres types de contenu (comme des images, des pièces jointes ou du HTML), et ce, en prenant en charge différents encodages de caractères au-delà de l'ASCII. Pour assurer une compatibilité maximale entre les différents clients de messagerie, on utilise généralement la version "1.0", car c'est la norme courante et universellement acceptée :
Si vous désirez obtenir plus d'informations sur le sujet, je vous conseille la lecture de cet excellent article sur le site d'alsacréations.<?php // Version MIME utilisée dans le message. $entetes = ["MIME-Version" => "1.0"]; ?> - Content-Type (Type de Contenu) : Cet en-tête indique le type de contenu ainsi que le jeu de caractères utilisé pour représenter ce contenu. Cela permet au client de messagerie de savoir comment interpréter les octets reçus en termes de caractères :
- text/plain : Indique que le contenu du courriel est en texte brut, sans mise en forme spécifique. C'est le type par défaut si aucun autre type n'est spécifié. Il est souvent utilisé pour les courriels contenant simplement du texte.
- text/html : Indique que le contenu du courriel est au format HTML, permettant l'inclusion de balises HTML pour une mise en page plus poussée.
- multipart/mixed : Utilisé lorsque le courriel contient plusieurs parties de contenu de types différents, comme du texte et des pièces jointes. Ce type permet de combiner différents types de contenu dans un seul courriel.
- multipart/alternative : Similaire à multipart/mixed, mais utilisé lorsque le courriel contient plusieurs versions alternatives du même contenu, par exemple une version HTML et une version texte brut. Le client de messagerie choisira la version la mieux adaptée à ses capacités.
<?php // "text/html" indique que le contenu du courriel est au format HTML. // "charset" spécifie l'encodage des caractères. Par exemple, "UTF-8" permet d'afficher correctement // les caractères de différentes langues. Cela garantit que les caractères spéciaux et accentués sont // interprétés correctement par le client de messagerie. $entete = ["Content-Type" => "text/html; charset=UTF-8"]; ?> - Content-Transfer-Encoding (Encodage de Transfert de Contenu) : Cet en-tête définit la méthode utilisée pour encoder le contenu lors de son transfert par email. Voici les principales méthodes et leurs usages :
- 7bit : Utilisé pour du texte contenant uniquement des caractères ASCII standards (valeurs de 0 à 127). C'est le mode par défaut si le contenu est strictement en ASCII.
- 8bit : Adapté lorsque le contenu peut contenir des octets avec des valeurs comprises entre 0 et 255. Ce mode nécessite que le serveur SMTP supporte l'extension 8BITMIME.
- base64 : À utiliser pour encoder du contenu binaire ou du texte riche en caractères non-ASCII. Cet encodage convertit l'intégralité du contenu en une chaîne composée uniquement de caractères ASCII.
- quoted-printable : Idéal pour du texte principalement en ASCII (0 à 127) avec quelques caractères non-ASCII. Seuls les caractères hors de la plage ASCII standard sont encodés sous forme de séquences =XX, préservant ainsi la lisibilité du contenu.
<?php $entete = ["Content-Transfer-Encoding" => "quoted-printable"]; ?> - Content-Disposition (Disposition du Contenu) : Cet en-tête informe le client de messagerie sur la manière dont il doit afficher le contenu ou les pièces jointes du message. Il est particulièrement utile pour indiquer si une pièce jointe doit être affichée directement dans le corps du message ou si elle doit être téléchargée en tant que fichier :
- inline : Le contenu s'affiche directement dans le message.
- attachment : Le contenu est traité comme une pièce jointe et incite généralement l'utilisateur à le télécharger.
<?php $entete = ["Content-Disposition" => "attachment; filename=\"exemple.pdf\""]; ?>
Encodage et champ Subject
L'encodage spécifié dans Content-Transfer-Encoding s'applique uniquement au corps du message (HTML ou texte). Il ne s'applique pas au champ Subject de l'email.
Si votre sujet contient des caractères spéciaux (comme des accents), vous devez l'encoder séparément selon la norme MIME, en utilisant soit : Q-encoding (quoted-printable), soit B-encoding (base64).
Contrairement au contenu du message, ce champ doit obligatoirement être encapsulé dans une syntaxe standardisée MIME, sinon il risque de ne pas être décodé correctement par les clients de messagerie.
Voici un exemple d'encodage du sujet avec la méthode Q (quoted-printable). Ce format utilise un en-tête MIME sous la forme :=?ENCODAGE?ENCODAGE_TYPE?TEXTE_ENCODE?=
// Sujet original contenant des caractères accentués.
$sujet = "Message envoyé à l'administrateur";
// Encodage du texte en Quoted-Printable.
$sujetEncode = quoted_printable_encode($sujet);
// Remplacement des espaces par des underscores (recommandé en Q-Encoding).
$sujetEncode = str_replace(' ', '_', $sujetEncode);
// Encapsulation selon la syntaxe MIME.
$sujetFinal = "=?UTF-8?Q?" . $sujetEncode . "?=";
// Résultat :
// "=?UTF-8?Q?Message_envoy=C3=A9_=C3=A0_l=E2=80=99administrateur?="
Cela garantit que le champ Subject sera correctement affiché dans tous les clients mails, y compris ceux qui n'interprètent que les caractères ASCII de base.
En revanche, pour le corps du message, cette encapsulation n'est pas nécessaire : c'est l'en-tête Content-Transfer-Encoding qui informe le client de l'encodage utilisé. Une fois cette en-tête présente, le contenu est décodé automatiquement sans que le corps ait besoin d'un format spécifique.
Voici un exemple de configuration d'en-têtes pour un courriel dont le contenu est au format HTML avec quelques caractères ASCII étendus :
<?php
// 1. Expéditeur du courriel.
$expediteur = "Claudy Focan <claudy.focan@dikkenek.be>";
// 2. Destinataire du courriel.
$destinataire = "Maman Focan <maman.focan@dikkenek.be>";
// 3. Sujet du courriel.
$sujet = "Test d'envoi du courriel au format HTML";
// Encodage du sujet en Quoted-Printable.
$sujet = quoted_printable_encode($sujet);
// Remplacement des espaces par des underscores (recommandé en Q-Encoding).
$sujet = str_replace(' ', '_', $sujet);
// Encapsulation selon la syntaxe MIME.
$sujet = "=?UTF-8?Q?" . $sujet . "?=";
// 4. Configurer les en-têtes.
$entetes = [
"From" => $expediteur,
"MIME-Version" => "1.0",
"Content-Type" => "text/html; charset=\"UTF-8\"",
"Content-Transfer-Encoding" => "quoted-printable"
];
// 5. Corps du message au format HTML.
ob_start();
?>
<html>
<body>
<p>Maman,</p>
<p>Je suis dégoûté, je viens de me faire carjackey !</p>
<p>Bisou,</p>
<p>Claudy.</p>
</body>
</html>
<?php
$message = ob_get_clean();
// Encodage en quoted-printable.
// Limite automatiquement les lignes à 76 caractères, encode les caractères spéciaux
// et prévient toute mauvaise interprétation de fin de message par les serveurs SMTP.
// Il ne faut donc plus utiliser ni "wordwrap()" pour limiter la longueur des lignes,
// ni "str_replace()" pour les points.
$message = quoted_printable_encode($message);
// 6. Tentative d'envoi du courriel :
if (mail($destinataire, $sujet, $message, $entetes))
{
echo "Le courriel a été envoyé avec succès.";
}
else
{
echo "L'envoi du courriel a échoué.";
}
?>
Notez qu'il est aussi possible de configurer les en-têtes sous forme d'une chaîne de caractères plutôt que sous forme de tableau. Si vous optez pour cette méthode, assurez-vous de terminer chaque ligne d'en-tête avec la séquence \r\n. Cette séquence indique un retour à la ligne, permettant ainsi aux serveurs de messagerie d'interpréter correctement ces derniers. Notez que l'utilisation des doubles guillemets est obligatoire pour que la séquence soit interprétée correctement :
<?php
$entete = "MIME-Version: 1.0";
$entete .= "Content-Type: text/html; charset=UTF-8\r\n";
$entete .= "Content-Transfer-Encoding: quoted-printable\r\n";
$entete .= "From: Claudy Focan <claudy.focan@dikkenek.be>\r\n";
?>
Exercices - Part 02
Exo-envoi-de-courriel-02
- Objectif : Simuler la soumission d'un formulaire de contact déclenchant l'envoi d'un courriel, en configurant les en-têtes pour définir l'expéditeur, le format et l'encodage du message avec les réglages appropriés. Vérifier ensuite la réception et l'affichage du courriel à l'aide de MailHog.
- Instructions :
- Assurez-vous que MailHog est installé et en cours d'exécution. Si ce n'est pas encore fait, référez-vous au chapitre l'envoi de courriels en local.
- Créez un nouveau dossier nommé exo-envoi-de-courriel-02.
- Dans ce dossier, créez un fichier nommé index.php.
- Dans ce fichier, écrivez un script PHP qui envoie un courriel avec les spécifications suivantes :
- Sujet : IMOSUP : Message provenant de la page contact.
- Destinataire : secretariat@imosup.waf.be.
- Message au format HTML simulant la demande d'inscription d'un utilisateur via le formulaire de la page contact :
<html> <body> <p>Un utilisateur a soumis une demande via le formulaire de contact :</p> <ul> <li><b>Nom :</b> Focan</li> <li><b>Prénom :</b> Claudy</li> <li><b>Email :</b> claudy.focan@gmail.com</li> <li><b>Sujet :</b> Inscription</li> <li><b>Message :</b> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Atque aspernatur cumque iste rerum consectetur exercitationem soluta a nihil tenetur debitis, nesciunt, sint, ipsum autem veniam amet delectus minus necessitatibus expedita?</li> </ul> </body> </html> - Les en-têtes suivants doivent être définis :
- Expéditeur du courriel : Page Contact <bot@imosup.waf.be>.
- Version MIME pour assurer la compatibilité.
- Type de contenu approprié.
- Encodage de transfert approprié.
- Ouvrez MailHog dans votre navigateur à l'adresse suivante : http://localhost:8025.
- Dans le terminal, placez-vous dans le dossier exo-envoi-de-courriel-02 et exécutez le fichier avec la commande : php index.php.
- Vérifiez si le courriel a bien été reçu dans MailHog. Ouvrez-le, puis cliquez sur Show headers pour afficher les en-têtes et vous assurer qu'ils ont été correctement configurés.
Les Pièces-jointes
La fonction mail() permet aussi d'ajouter des pièces-jointes à un courriel. Malheureusement, cette fonction ne dispose pas d'un simple argument dans lequel passer les fichiers. Les pièces-jointes doivent être ajoutées manuellement dans le corps du message. Pour que les serveurs de messagerie puissent distinguer les différentes éléments du corps du courriel, il faut utiliser une séquence de caractères unique pour séparer ceux-ci. Cette séquence, aussi appelée "boundary" (limite, frontière) doit être unique pour qu'elle ne puisse pas être confondue avec les éléments qu'elle sépare.
Voici une façon de générer cette séquence :
<?php
$boundary = md5(uniqid(mt_rand(), true));
?>
- uniqid() : Génère un identifiant unique basé sur la date et l'heure actuelles. Le premier argument est ajoutée en tant que préfixe à la valeur de sortie. Si "true" est passé en second argument, un suffixe aléatoire est lui aussi ajouté à la valeur de sortie.
- mt_rand() : Génère un nombre aléatoire.
- md5() : Calcule la valeur de hachage MD5 de la combinaison de l'identifiant unique généré. Cela crée une chaîne de caractères de 32 caractères hexadécimaux. Le hashage est un processus de transformation de données en une valeur de longueur fixe et irréversible.
Une autre particularité lorsque l'on désire envoyer un courriel avec des pièces-jointes, c'est qu'en plus de l'en-tête général, il faudrait configurer un en-tête individuel au sein du corps de celui-ci avant chaque partie (message, pièce-jointe, ...).
Voici l'exemple d'un courriel accompagné d'un fichier au format PDF :
<?php
// Expéditeur du courriel.
$expediteur = "Claudy Focan <claudy.focan@dikkenek.be>";
// Destinataire du courriel.
$destinataire = "Maman Focan <maman.focan@dikkenek.be>";
// Sujet du courriel.
$sujet = "Brochure Stannah";
// Chemin vers le fichier PDF.
$fichierChemin = __DIR__ . DIRECTORY_SEPARATOR . "chemin" . DIRECTORY_SEPARATOR . "vers" . DIRECTORY_SEPARATOR . "le" . DIRECTORY_SEPARATOR . "fichier.pdf";
// Récupérer le type MIME du fichier.
$typeMime = mime_content_type($fichierChemin);
// Récuperer le nom du fichier.
$nomFichier = basename($fichierChemin);
// Récupérer le contenu du fichier.
$fichierContenu = file_get_contents($fichierChemin);
// Encodage du fichier en base64 :
// La fonction "chunk_split" divise une chaîne en morceaux plus petits. Par défaut, la division s'effectue tous les
// 76 caractères et les segments sont séparés par la séquence "\r\n".
// Cependant, ces deux valeurs sont configurable à l'aide du second et du troisième argument. Cette fonction est
// souvent utilisée pour formater les données binaires encodées en base64.
// Cela permet de rendre les données compatibles avec certaines restrictions de taille dans certains protocoles.
// La fonction "base64_encode()" convertit ces données binaires en une représentation qui ne contient que des
// caractères ASCII, assurant ainsi la compatibilité.
$fichierContenuBase64 = chunk_split(base64_encode($fichierContenu));
// Générer la séquence permettant de distinguer les parties du corps du message.
$boundary = md5(uniqid(microtime(), TRUE));
// Configurer les en-têtes :
// MIME-Version (Extensions multifonctions du courrier Internet) : Permet aux clients de messagerie de traiter correctement
// les parties du message qui peuvent contenir des données multimédias ou d'autres types de contenu non ASCII.
// Content-Type : Spécifie que le message est composé de plusieurs parties (multipart), contenant à la fois du
// texte et des pièces jointes (mixed), avec un délimiteur spécifié par la variable "$boundary" pour séparer ces parties.
$entetes = [
"From" => $expediteur,
"MIME-Version" => "1.0",
"Content-Type" => "multipart/mixed; boundary=$boundary"
];
// Corps du message au format HTML.
ob_start();
?>
<html>
<body>
<p>Maman,</p>
<p>Voici un fichier PDF avec les caractéristiques de ton futur monte-escaliers.</p>
<p>Bisou,</p>
<p>Claudy.</p>
</body>
</html>
<?php
$message = ob_get_clean();
// Encodage en quoted-printable.
// Limite automatiquement les lignes à 76 caractères, encode les caractères spéciaux
// et prévient toute mauvaise interprétation de fin de message par les serveurs SMTP.
// Il ne faut donc plus utiliser ni "wordwrap()" pour limiter la longueur des lignes,
// ni "str_replace()" pour les points.
$message = quoted_printable_encode($message);
// Monter le corps du courriel :
$corps = [];
// Partie 1 : le message HTML :
$corps[] = "--$boundary"; // Indique le début d'une nouvelle partie du message avec le délimiteur (boundary).
$corps[] = "Content-Type: text/html; charset=UTF-8"; // Spécifie que le contenu est en HTML et utilise l'encodage UTF-8.
$corps[] = "Content-Transfer-Encoding: quoted-printable"; // Définit l'encodage utilisé pour le contenu HTML.
$corps[] = ""; // Sépare les en-têtes de la partie contenu avec une ligne vide, comme l'exige la norme MIME.
$corps[] = $message; // Contenu HTML du message encodé en quoted-printable.
// Partie 2 : la pièce jointe (l'image) :
$corps[] = "--$boundary"; // Indique le début d'une nouvelle partie du message avec le délimiteur (boundary).
$corps[] = "Content-Type: $typeMime; name=$nomFichier"; // Type MIME du fichier et son nom.
$corps[] = "Content-Disposition: attachment; filename=$nomFichier"; // Indique que le fichier est une pièce jointe avec son nom.
$corps[] = "Content-Transfer-Encoding: base64"; // Spécifie que le contenu est encodé en base64.
$corps[] = ""; // Sépare les en-têtes de la pièce jointe avec une ligne vide, comme l'exige la norme MIME.
$corps[] = $fichierContenuBase64; // Contenu de la pièce jointe encodé en base64.
// Préciser qu'il s'agit de la limite finale en la préfixant et en la suffixant de "--".
$corps[] = "--$boundary--";
// Utilisation de la fonction "implode()" pour transformer le corps en chaîne de caractères en séparant chaque
// élément par la séquence de retour à la ligne "\r\n".
$corps = implode("\r\n", $corps);
// Tentative d'envoi du courriel :
if (mail($destinataire, $sujet, $corps, $entetes))
{
echo "Le courriel a été envoyé avec succès.";
}
else
{
echo "L'envoi du courriel a échoué.";
}
?>
Exercices - Part 03
Exo-envoi-de-courriel-03
- Objectif : Automatiser l'envoi d'un courriel de bienvenue suite à l'inscription d'un utilisateur sur un site web. Le courriel doit contenir un message HTML ainsi qu'une image en pièce jointe. Tester ensuite l'envoi et la réception du courriel à l'aide de MailHog.
- Instructions :
- Créez un nouveau dossier nommé exo-envoi-de-courriel-03.
- Dans ce dossier, créez un dossier nommé images.
- Recherchez une image placez-la dans le dossier images de votre projet.
- À la racine du projet, créez un fichier nommé index.php.
- Dans ce fichier, écrivez un script PHP qui simule l'inscription d'un utilisateur et déclenche l'envoi automatique d'un courriel de bienvenue avec les spécifications suivantes :
- Sujet : Bienvenue chez IMOSUP !.
- Destinataire : Adresse courriel fictive d'un nouvel utilisateur, par exemple nouveau@exemple.com.
- Message au format HTML contenant un message de bienvenue :
<html> <body> <p>Bonjour,</p> <p>Bienvenue sur notre site ! Nous sommes ravis de vous compter parmi nos membres.</p> <p>En pièce jointe, vous trouverez une image de bienvenue ainsi que nos premières recommandations.</p> <p>À très bientôt,<br>L'équipe IMOSUP</p> </body> </html> - Une image en pièce jointe représentant un message de bienvenue.
- Les en-têtes suivants doivent être définis :
- Expéditeur du courriel : IMOSUP <welcome@imosup.waf.be>.
- Version MIME pour assurer la compatibilité.
- Type de contenu approprié.
- Encodage de transfert approprié.
- Délimiteur unique pour séparer les différentes parties du message.
- Ouvrez MailHog dans votre navigateur à l'adresse suivante : http://localhost:8025.
- Dans le terminal, placez-vous dans le dossier exo-envoi-de-courriel-03 et exécutez le fichier avec la commande : php index.php.
- Vérifiez si le courriel a bien été reçu dans MailHog. Ouvrez-le et cliquez sur Show headers pour afficher les en-têtes et vous assurer qu'ils ont été correctement configurés. Ensuite, accédez à l'onglet MIME pour vérifier que la pièce jointe est bien présente. Cliquez sur Download pour la télécharger, puis ouvrez l'image afin de vérifier qu'elle est exploitable.
Exercice : Projet Progressif 03
- Objectif : Mettre en place un système d'envoi de courriels depuis le formulaire de contact, permettant aux utilisateurs de contacter le gestionnaire du site.
- Instructions :
- Poursuivre le projet progressif initié lors du chapitre sur les modèles de pages dynamiques.
- Ajoutez une fonctionnalité permettant d'envoyer le contenu du formulaire de contact par courriel au gestionnaire du site après sa soumission. L'envoi ne devra se faire que si tous les champs du formulaire sont valides. Pour cet exercice, utilisez votre propre adresse de courriel comme destinataire.
- Configurez l'envoi du courriel avec :
- Un en-tête complet et approprié, incluant les champs suivants : From, To, Subject, Content-Type, Content-Transfer-Encoding, etc.
- Un sujet pertinent, par exemple : Projet Framework - Formulaire de contact.
- Un message structuré en HTML contenant les informations saisies par l'utilisateur.
- Pour cet exercice, utilisez une adresse de courriel réelle que vous possédez comme destinataire. Cela vous permettra, lors des futurs tests une fois l'application en ligne, de vérifier si l'envoi de courriels se déroule correctement.
- Testez la réception du courriel en local à l'aide de Laragon, MailHog ou tout autre outil de gestion des courriels en environnement de développement.