Discussion:
Envoi de mail, champ headers (was: Problème PHP)
(trop ancien pour répondre)
Olivier Miakinen
2016-09-23 09:34:02 UTC
Permalink
[...] je cherche à envoyer un courriel (un mail en
franglais) dans un script PHP et que j'ai du mal avec le champ headers
(dont je veux bien qu'on m'explique toutes les subtilités ici ou
ailleurs).
Ok, je redirige vers fr.comp.lang.php.

Je suppose que tu utilises cette fonction d'envoi de courriel en PHP :
<http://php.net/manual/fr/function.mail.php>. Quels problèmes as-tu
exactement ?
--
Olivier Miakinen
Jean Francois Ortolo
2016-09-23 10:43:20 UTC
Permalink
Post by Olivier Miakinen
[...] je cherche à envoyer un courriel (un mail en
franglais) dans un script PHP et que j'ai du mal avec le champ headers
(dont je veux bien qu'on m'explique toutes les subtilités ici ou
ailleurs).
Ok, je redirige vers fr.comp.lang.php.
<http://php.net/manual/fr/function.mail.php>. Quels problèmes as-tu
exactement ?
Bonjour Monsieur Mazarian

C'est vrai que la fonction php mail() pose des problèmes pratiques de
fiabilité d'envoi de mails.

Je préconise la classe php : PHPMailer.

Avec cette classe PHPMailer, envoyer des mails est un jeu d'enfant.

Amicalement.

Jean FRançois Ortolo
Eric Demeester
2016-09-24 10:28:58 UTC
Permalink
Bonjour,

Jean Francois Ortolo (Fri, 23 Sep 2016 12:43:20 +0200 -
Post by Jean Francois Ortolo
C'est vrai que la fonction php mail() pose des problèmes pratiques de
fiabilité d'envoi de mails.
Pour ma part, je l'utilise depuis bien des années et je n'ai jamais
rencontré de problème, mais il est vrai qu'elle nécessite de la rigueur,
en particulier dans la définition des en-têtes des courriers (celles par
défaut sont insuffisantes), et qu'elle peut s'avérer complexe à utiliser
dès qu'on a des besoins un peu compliqués (html, pièces jointes, etc.).
Post by Jean Francois Ortolo
Je préconise la classe php : PHPMailer.
Avec cette classe PHPMailer, envoyer des mails est un jeu d'enfant.
Cette classe est effectivement très pratique, elle permet par exemple,
contrairement à la fonction mail(), de faire appel très simplement à un
serveur SMTP si on en a un à disposition, alors qu'avant, j'étais obligé
de programmer de tels envois entièrement à la main.

Bref, je te rejoins, si cette classe est disponible dans l'environnement
utilisé (point à vérifier si le site est sur un hébergement mutualisé),
mieux vaut l'utiliser plutôt que la fonction mail().

On peut trouver un didacticiel et des liens de téléchargment ici :
http://stephaneey.developpez.com/tutoriel/php/phpmailer/
Otomatic
2016-09-24 13:12:49 UTC
Permalink
Post by Eric Demeester
http://stephaneey.developpez.com/tutoriel/php/phpmailer/
Je plusssoie énergiquement.
Cela fait des années que j'utilise la class PhpMailer pour mes
formulaires de contact.
Ça fonctionne parfaitement avec des smtp authentifiés chez Gandi, OVH ou
1and1. Et il n'y a pas de raison que ça ne fonctionne pas pour les
autres.
--
Un ordinateur résout des problèmes que nous n'aurions pas sans lui
Technique aéronautique : http://aviatechno.net
Serge Nazarian
2016-09-26 09:03:18 UTC
Permalink
Post by Olivier Miakinen
[...] je cherche à envoyer un courriel (un mail en
franglais) dans un script PHP et que j'ai du mal avec le champ headers
(dont je veux bien qu'on m'explique toutes les subtilités ici ou
ailleurs).
Ok, je redirige vers fr.comp.lang.php.
<http://php.net/manual/fr/function.mail.php>. Quels problèmes as-tu
exactement ?
Bonjour,

Je ne sais pas si ce que je mets dans $header est correct :
$header .= "From :".$nom." <".$email."> /r/n"
car l'affichage avec echo n'est pas bon, mais peut-être que l'envoi
avec $mail de PHP est bon quand même, d'après ce que je lis dans
<http://php.net/manual/fr/function.mail.php>.

Cordialement.
--
Serge Nazarian
Pour m'écrire directement : http://cerbermail.com/?ZDkROVSJlu
Olivier Miakinen
2016-09-26 10:26:12 UTC
Permalink
Post by Eric Demeester
Post by Olivier Miakinen
<http://php.net/manual/fr/function.mail.php>. Quels problèmes as-tu
exactement ?
Bonjour,
Non, ça ne l'est pas en effet. Je ne suis pas sûr de voir toutes les
erreurs car je ne connais pas le contenu de $header, $nom et $email
avant l'appel, mais il y a des erreurs évidentes rien que dans ce
que tu montres.
Post by Eric Demeester
$header .=
Puisque tu ajoutes quelque chose à un $header existant, il faudrait
déjà savoir ce qu'il y a dedans *avant*.
Post by Eric Demeester
"From :"
Mettre l'espace après les deux-points et pas avant :
"From: "
Post by Eric Demeester
.$nom." <".$email.
Il faudrait que $nom et $email soient syntaxiquement corrects, mais
je ne peux pas en juger comme ça. J'espère qu'ils ne viennent pas
directement d'une requête faite à l'utilisateur, sans contrôle, car
sinon ton script peut être utilisé pour spammer la terre entière.
Je ne plaisante pas.
Post by Eric Demeester
"> /r/n"
Ça c'est la plus grosse erreur : \r\n et pas /r/n. Note que
l'espace avant n'est pas utile et pourrait être supprimée.
Post by Eric Demeester
car l'affichage avec echo n'est pas bon, mais peut-être que l'envoi
avec $mail de PHP est bon quand même, d'après ce que je lis dans
<http://php.net/manual/fr/function.mail.php>.
:-D

Habituellement, on lit dans les forums d'entraide « ce que j'envoie
semble correct mais ça ne fonctionne pas ». Il est plus inhabituel
de lire « ce que j'envoie est incorrect mais ça devrait fonctionner
quand même »...
--
Olivier Miakinen
Eric Demeester
2016-09-26 14:16:03 UTC
Permalink
Bonjour,
Post by Olivier Miakinen
Post by Serge Nazarian
"> /r/n"
Ça c'est la plus grosse erreur : \r\n et pas /r/n. Note que
l'espace avant n'est pas utile et pourrait être supprimée.
Dans de nombreux cas (systèmes Unix en particulier), le "\r" est inutile
voire nocif car risquant d'insérer des lignes vides, "\n" suffit.
Post by Olivier Miakinen
Habituellement, on lit dans les forums d'entraide « ce que j'envoie
semble correct mais ça ne fonctionne pas ». Il est plus inhabituel
de lire « ce que j'envoie est incorrect mais ça devrait fonctionner
quand même »...
La syntaxe est correcte, mais pour envoyer un courrier, pas pour
l'affichage dans une page HTML via echo ou print.

Voici un exemple qui fonctionne, servant à l'envoi d'un courrier de
confirmation suite au remplissage d'un formulaire en ligne, mais c'est
généralisable à tout envoi en texte brut :

// En-têtes du mail
// Expéditeur
$entete = "From: Expediteur <***@domaine.tld>\n";

// Copie caché au gestionnaire du formulaire
$entete .= "Bcc: ***@domaine2.tld\n";

// Précisions concernant le format d'envoi
$entete .= "MIME-Version: 1.0\n";
$entete .= "Content-type: text/plain; charset=UTF-8\n";
$entete .= "Content-Transfer-Encoding: quoted-printable\n";

// Destinataire
$destinataire = "***@example.com";

// Sujet
$sujet = "Compte-rendu des informations de votre formulaire"

// Corps du message
$message = "Bla bla bla";

// Envoi
$mail_ok = mail($destinataire, $subject, $message, $entete);
Serge Nazarian
2016-09-27 07:13:16 UTC
Permalink
Post by Eric Demeester
Bonjour,
Post by Olivier Miakinen
Post by Serge Nazarian
"> /r/n"
Ça c'est la plus grosse erreur : \r\n et pas /r/n. Note que
l'espace avant n'est pas utile et pourrait être supprimée.
Dans de nombreux cas (systèmes Unix en particulier), le "\r" est inutile
voire nocif car risquant d'insérer des lignes vides, "\n" suffit.
Post by Olivier Miakinen
Habituellement, on lit dans les forums d'entraide « ce que j'envoie
semble correct mais ça ne fonctionne pas ». Il est plus inhabituel
de lire « ce que j'envoie est incorrect mais ça devrait fonctionner
quand même »...
La syntaxe est correcte, mais pour envoyer un courrier, pas pour
l'affichage dans une page HTML via echo ou print.
Voici un exemple qui fonctionne, servant à l'envoi d'un courrier de
confirmation suite au remplissage d'un formulaire en ligne, mais c'est
// En-têtes du mail
// Expéditeur
// Copie caché au gestionnaire du formulaire
// Précisions concernant le format d'envoi
$entete .= "MIME-Version: 1.0\n";
$entete .= "Content-type: text/plain; charset=UTF-8\n";
$entete .= "Content-Transfer-Encoding: quoted-printable\n";
// Destinataire
// Sujet
$sujet = "Compte-rendu des informations de votre formulaire"
// Corps du message
$message = "Bla bla bla";
// Envoi
$mail_ok = mail($destinataire, $subject, $message, $entete);
Merci.
Mais $entete = "From: Expediteur <***@domaine.tld>\n";
doit utiliser des variables postées dans un formulaire, $nom pour
Expediteur et $email pour ***@domaine.tld.
Est-ce que $entete = "From: ".$nom." <".$email.">\n"; est correct ?
--
Serge Nazarian
Pour m'écrire directement : http://cerbermail.com/?ZDkROVSJlu
Olivier Miakinen
2016-09-27 08:59:28 UTC
Permalink
Post by Serge Nazarian
doit utiliser des variables postées dans un formulaire, $nom pour
Hum. Je vais répondre à ton autre message à ce propos.
Post by Serge Nazarian
Est-ce que $entete = "From: ".$nom." <".$email.">\n"; est correct ?
Oui, ou plus simplement : $entete = "From: $nom <$email>\n";
--
Olivier Miakinen
Serge Nazarian
2016-09-27 07:18:49 UTC
Permalink
Post by Olivier Miakinen
Il faudrait que $nom et $email soient syntaxiquement corrects, mais
je ne peux pas en juger comme ça. J'espère qu'ils ne viennent pas
directement d'une requête faite à l'utilisateur, sans contrôle, car
sinon ton script peut être utilisé pour spammer la terre entière.
Je ne plaisante pas.
Peux-tu m'en dire un peu plus sur le risque de « spammer la terre
entière » car effectivement $nom et $email proviennent d'un formulaire
rempli par l'utilisateur.
--
Serge Nazarian
Pour m'écrire directement : http://cerbermail.com/?ZDkROVSJlu
Olivier Miakinen
2016-09-27 09:20:23 UTC
Permalink
Post by Serge Nazarian
Post by Olivier Miakinen
Il faudrait que $nom et $email soient syntaxiquement corrects, mais
je ne peux pas en juger comme ça. J'espère qu'ils ne viennent pas
directement d'une requête faite à l'utilisateur, sans contrôle, car
sinon ton script peut être utilisé pour spammer la terre entière.
Je ne plaisante pas.
Peux-tu m'en dire un peu plus sur le risque de « spammer la terre
entière » car effectivement $nom et $email proviennent d'un formulaire
rempli par l'utilisateur.
Très volontiers.

Dans un courriel, ce qui sépare les entêtes du contenu du message,
c'est juste deux sauts de ligne de suite. Avoir un contrôle sur une
partie du contenu d'un entête suffit alors pour ajouter d'une part
de nombreux autres entêtes, d'autre part le corps du message lui-même.

Pour cela, il suffit que le paramètre $nom ou $email contienne par
exemple :
"\n
Subject: achetez mon beau produit\n
To: <adresse_spammée_1>\n
To: <adresse_spammée_2>\n
...
To: <adresse_spammée_3000>\n
\n
J'ai un superbe produit à vendre, achetez-le.\n
Allez sur <site_de_spam>.\n
...
...\n"

Le spammeur peut faire mieux, d'abord en complétant le champ From
au lieu de l'interrompre brutalement, et aussi en envoyant son
spam en MIME Multipart, ce qui relègue le *vrai* contenu de ton
message dans une zone cachée (il ne reste donc plus que le spam
et rien d'autre).

Heureusement, on peut s'en protéger. La solution /a minima/ consiste
à vérifier que les champs $nom et $email ne contiennent aucun saut
de ligne.

Tu peux aller plus loin, en vérifiant d'abord que l'adresse de courriel
est syntaxiquement correcte : <http://faqfclphp.free.fr/#rub5.3>. Pour
bien faire, il faudrait aussi encoder le nom selon MIME (RFC 2047) si
jamais il contient des caractères non ASCII, mais je parierais bien
que la classe PHPMailer indiquée par Jean-François sait le faire.
--
Olivier Miakinen
Serge Nazarian
2016-09-27 09:28:26 UTC
Permalink
Post by Olivier Miakinen
Post by Serge Nazarian
Post by Olivier Miakinen
Il faudrait que $nom et $email soient syntaxiquement corrects, mais
je ne peux pas en juger comme ça. J'espère qu'ils ne viennent pas
directement d'une requête faite à l'utilisateur, sans contrôle, car
sinon ton script peut être utilisé pour spammer la terre entière.
Je ne plaisante pas.
Peux-tu m'en dire un peu plus sur le risque de « spammer la terre
entière » car effectivement $nom et $email proviennent d'un formulaire
rempli par l'utilisateur.
Très volontiers.
Dans un courriel, ce qui sépare les entêtes du contenu du message,
c'est juste deux sauts de ligne de suite. Avoir un contrôle sur une
partie du contenu d'un entête suffit alors pour ajouter d'une part
de nombreux autres entêtes, d'autre part le corps du message lui-même.
Pour cela, il suffit que le paramètre $nom ou $email contienne par
"\n
Subject: achetez mon beau produit\n
To: <adresse_spammée_1>\n
To: <adresse_spammée_2>\n
...
To: <adresse_spammée_3000>\n
\n
J'ai un superbe produit à vendre, achetez-le.\n
Allez sur <site_de_spam>.\n
...
...\n"
Le spammeur peut faire mieux, d'abord en complétant le champ From
au lieu de l'interrompre brutalement, et aussi en envoyant son
spam en MIME Multipart, ce qui relègue le *vrai* contenu de ton
message dans une zone cachée (il ne reste donc plus que le spam
et rien d'autre).
Heureusement, on peut s'en protéger. La solution /a minima/ consiste
à vérifier que les champs $nom et $email ne contiennent aucun saut
de ligne.
Tu peux aller plus loin, en vérifiant d'abord que l'adresse de courriel
est syntaxiquement correcte : <http://faqfclphp.free.fr/#rub5.3>. Pour
bien faire, il faudrait aussi encoder le nom selon MIME (RFC 2047) si
jamais il contient des caractères non ASCII, mais je parierais bien
que la classe PHPMailer indiquée par Jean-François sait le faire.
Merci pour cette très claire explication.
--
Serge Nazarian
Pour m'écrire directement : http://cerbermail.com/?ZDkROVSJlu
Loading...