Envoyer un email en PHP : mail(), PHPMailer, Brevo, Resend
Envoyer un email en PHP sans finir en spam : la fonction mail(), PHPMailer en SMTP, Brevo et Resend en API, les tests en local et les pièges à éviter.

La fonction mail() de PHP : simple, mais fragile
PHP sait expédier un message tout seul grâce à mail(), sa fonction native. Mais cette fonction ne parle pas à Internet. Elle transmet le message au MTA du serveur (le logiciel d'envoi, en général Postfix ou Sendmail), qui assure la livraison. MTA mal réglé ou coupé par l'hébergeur ? Rien ne part, et aucune erreur claire ne vous aide à comprendre pourquoi.
Les paramètres to, subject, message et headers
Une ligne suffit : mail($to, $subject, $message, $headers). Dans $to, on place l'adresse du destinataire ; $subject porte l'objet, $message le texte, et $headers les en-têtes supplémentaires. C'est ce dernier paramètre qui accueille l'expéditeur, via un header From, par exemple From: contact@votre-domaine.com.
Vous envoyez du HTML avec des accents ? Deux en-têtes deviennent alors indispensables : MIME-Version: 1.0 et Content-Type: text/html; charset=utf-8. Oubliez le bon charset, et un prénom comme Hélène se change en suite de signes illisibles. Reste à tester le retour de la fonction avec une condition : if (mail(...)) { echo 'le message est parti'; } else { echo 'Erreur d’envoi'; }.
Pourquoi elle ne suffit pas pour un site professionnel
Votre message part de l'adresse IP de l'hébergeur, que partagent souvent des centaines d'autres sites. Qu'un seul d'entre eux envoie du spam, et c'est votre réputation qui trinque. En face, Gmail ou Outlook contrôlent que le serveur a bien le droit d'écrire au nom de votre domaine. Ce contrôle repose sur SPF, DKIM et DMARC, que mail() gère mal sur un hébergement mutualisé.
Envoyer un e-mail en SMTP avec PHPMailer
Pour envoyer un e-mail en PHP, PHPMailer reste la bibliothèque la plus utilisée. Elle ouvre une connexion à un vrai serveur SMTP, identifiant et mot de passe à l'appui, exactement comme votre logiciel de messagerie. Pièces jointes, HTML, encodage, messages d'erreur détaillés : tout est prévu.
Installation et premier script
Commencez par créer le projet avec Composer, puis lancez composer require phpmailer/phpmailer. En tête de script, chargez la bibliothèque via require 'vendor/autoload.php' et importez la class PHPMailer. Ensuite, l'ordre ne varie jamais :
- Instanciez l'objet : $mail = new PHPMailer(true); le paramètre true active les exceptions.
- Côté SMTP, appelez $mail->isSMTP(), puis indiquez l'hôte, le port (587 avec STARTTLS ou 465 en SSL) et $mail->SMTPAuth = true.
- L'identifiant va dans $mail->Username, le mot de passe dans $mail->Password : lisez-les depuis un fichier de configuration rangé hors du dossier public.
- Pour l'encodage, $mail->CharSet = 'UTF-8'.
- Expéditeur et destinataire se déclarent avec $mail->setFrom('contact@votre-domaine.com', 'Votre entreprise') puis $mail->addAddress('commercial@votre-domaine.com').
- Enfin, un $mail->addReplyTo() avec l'adresse du visiteur vous permet de lui répondre en un clic.
Remplir le Body, le sujet et les pièces jointes
Trois lignes règlent le contenu. L'objet va dans $mail->Subject, la version HTML dans $mail->Body, et une version text brute dans $mail->AltBody, pour les messageries qui n'affichent pas le HTML. Un devis en PDF à joindre ? $mail->addAttachment('devis.pdf') suffit, et rien ne vous empêche de répéter l'appel pour d'autres pièces jointes.
Gardez un corps HTML sobre : un gabarit du type <div class='entete'>Nouvelle demande</div> <div class='contenu'>…</div>, avec un style écrit en ligne, puisque les messageries ignorent la plupart des feuilles de style. Juste avant l'envoi, placez $mail->send() dans un bloc try. Ça échoue ? Le catch affiche $mail->ErrorInfo, qui pointe précisément ce qui coince.
Brevo ou Resend : passer par un service d'envoi
Réputation des adresses IP, authentification du domaine, suivi de la délivrabilité : un service d'envoi transactionnel prend en charge la partie la plus délicate. Votre code PHP ne bouge pas, seul le canal de sortie change. Si vous dirigez une entreprise, c'est l'option que je vous recommande. Vos e-mails arrivent, et vous savez lesquels ont été ouverts ou refusés.
Brevo en relais SMTP ou en API
Deux branchements sont possibles avec Brevo. Le plus rapide ? Conserver PHPMailer et remplacer l'hôte, l'identifiant et la clé SMTP par ceux fournis dans votre compte. L'autre voie passe par son API HTTP, avec le SDK PHP officiel ou une requête cURL : vous transmettez un objet qui contient l'expéditeur, le destinataire, le sujet et le contenu HTML.
Resend, pensé pour les développeurs
Chez Resend, tout passe par l'API, et le SDK PHP s'installe lui aussi via Composer. Quelques lignes suffisent : from, to, subject et html dans un tableau, et la réponse vous renvoie un identifiant de message. Brevo comme Resend exigent de vérifier votre domaine, en ajoutant des enregistrements DNS chez votre registrar, à côté de votre enregistrement MX.
- Votre site tourne déjà avec PHPMailer ? Prenez le relais SMTP : quelques minutes suffisent pour basculer.
- Besoin de webhooks (rebonds, plaintes, ouvertures) ou de modèles gérés côté service ? L'API s'impose.
- Avant de trancher, comparez les quotas d'envoi, la localisation des serveurs au regard du RGPD et la qualité des journaux.
Tester en local : MAMP, localhost et Gmail
Sur MAMP, XAMPP ou un autre serveur local, mail() ne part presque jamais, faute de MTA configuré. Inutile de bricoler le php.ini. Installez plutôt un faux serveur SMTP comme Mailpit : il intercepte tout ce que votre site envoie et l'affiche dans une interface web. Aucun risque, ainsi, d'écrire par erreur à un vrai client.
Autre possibilité : envoyer depuis localhost avec un compte Gmail. Hôte smtp.gmail.com, port 587, et un mot de passe d'application, généré une fois la validation en deux étapes activée. Pour tester, c'est pratique. Pour une entreprise en production, non. Si vous écrivez au nom de votre marque, préférez une adresse email professionnelle sur votre propre domaine.
Sécuriser et fiabiliser votre formulaire
Mal protégé, un formulaire d'envoi se transforme vite en relais à spam. Le principal danger porte un nom : l'injection d'en-têtes. Un robot glisse un retour à la ligne dans le champ e-mail, puis ajoute ses propres destinataires. PHPMailer traite déjà largement ce risque, c'est vrai. Vos contrôles n'en restent pas moins nécessaires.
If, else : valider avant d'envoyer
Récupérez chaque champ name du formulaire avec $_POST, jamais avec $_GET. Pour l'adresse, filter_var() et FILTER_VALIDATE_EMAIL font le travail ; pour le téléphone, preg_match avec un motif simple. Un contrôle échoue ? La branche else { echo 'Veuillez vérifier votre adresse e-mail'; } affiche au visiteur un message clair plutôt qu'une page blanche.
Le prénom et le message doivent passer par htmlspecialchars, avec l'option ENT_QUOTES, avant d'entrer dans le Body. Sans cette précaution, un visiteur malveillant peut injecter du code dans l'e-mail reçu : c'est ce qu'on appelle une faille XSS. Dernière couche de protection, un champ piège invisible ou un captcha, comme le détaille notre guide pour sécuriser un formulaire de contact.
Les pièges qui envoient vos e-mails en spam
- Un expéditeur d'un autre domaine : dans setFrom, mettez toujours votre domaine, jamais l'adresse du visiteur.
- Une adresse générique, webmaster@ ou no-reply@, sans vraie boîte derrière.
- Du HTML seul, sans version texte.
- Des liens href raccourcis, ou qui pointent vers un domaine autre que le vôtre.
- L'absence de SPF, DKIM et DMARC, première cause quand un mail arrive en spam.
Temps et budget : de quoi dépend la mise en place
Combien de temps faut-il ? Honnêtement, aucune durée standard ne vaut pour tous les sites. Tout dépend de l'état de votre code, de votre accès aux DNS et du nombre d'e-mails différents à envoyer. Brancher un formulaire de contact sur PHPMailer n'a rien à voir avec un site qui expédie des confirmations de commande, des factures en pièces jointes et des relances.
- L'accès aux DNS : sans les identifiants du registrar, impossible d'authentifier le domaine.
- Le nombre de modèles d'e-mails, et leur mise en forme sur mobile.
- Votre volume mensuel, qui oriente le choix du service d'envoi et de son offre.
- Le niveau de suivi attendu : simple réception, ou statistiques et webhooks reliés à un CRM.
- La reprise d'un ancien code fragile, qu'il faut parfois réécrire.
Chez RankerSquare, nous proposons un site vitrine sur-mesure dès 19,90 € par mois en abonnement, avec un formulaire de contact dont les messages arrivent vraiment. Vos envois sont plus complexes ? Contactez-nous : le reste se fait sur devis, selon votre besoin. Pour aller plus loin, découvrez notre offre de création de site internet.
Questions fréquentes
Le plus souvent, le message part bien mais se fait filtrer en spam, à moins que le serveur n'ait aucun MTA configuré. Jetez d'abord un œil au dossier spam, ensuite aux journaux de l'hébergeur. Vous utilisez mail() ? Passez à PHPMailer en SMTP authentifié et vérifiez SPF, DKIM et DMARC sur votre domaine.
mail() remet le message au serveur local sans authentification, et vous apprend peu de chose en cas d'échec. PHPMailer, lui, se connecte à un serveur SMTP avec identifiant et mot de passe, gère l'UTF-8 et les pièces jointes, et affiche des erreurs précises. Pour un site professionnel, je choisirais PHPMailer sans hésiter : il est nettement plus fiable.
Dans PHPMailer, indiquez l'hôte smtp.gmail.com, le port 587 et le chiffrement STARTTLS. Côté Google, activez la validation en deux étapes, puis générez un mot de passe d'application à placer dans Password. Parfait pour des tests. Pour un envoi régulier au nom de votre entreprise, en revanche, passez votre chemin.


