Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

problème avec les accents dans un envoi d'email par PHP

42 réponses
Avatar
METIS
Bonjour,
Bon, désolé, on en a déjà parlé mais moi, le soudoué du code, j'y arrive
pas.
Avec le code ci-dessous, je me fais envoyer un formulaire en PHP (récupéré
je ne sais plus où).
Le problème, c'est que les accents donnent...
Nathalie Mazé dans le champ De de l'email reçu
...et dans l'email lui même, j'ai comme résultat soit...
Téléphone : téléphone
...soit...
Téléphone : téléphone
...en fonction de ce que je mets dans la ligne :
$headers .= "Content-type: text/plain; charset=UTF-8\r\n";

Comme je n'y connais que couic, c'est au pif.
Et au pif, après 36 essais, j'arrive à rien.

Merci à celui qui m'aidera et merci à ceux qui supportent ma nullité
indécrotable.

---------code------------

<?php
extract($_POST,EXTR_OVERWRITE);
if(isset($_POST['captchaResult']))
{
session_start();
$_POST['captchaResult'] = strtolower($_POST['captchaResult']);
$_SESSION['captchaResult'] = strtolower($_SESSION['captchaResult']);
if($_POST['captchaResult'] === $_SESSION['captchaResult'])
{ //captcha OK on envoi le message
$nom=$HTTP_POST_VARS['nom'];
$mail=$HTTP_POST_VARS['mail'];

/////voici la version Mine
$headers = "MIME-Version: 1.0\r\n";

//////ici on détermine le mail en format texte
//$headers .= "Content-type: text/plain; charset=iso-8859-1\r\n"; ligne
neutralisée
$headers .= "Content-type: text/plain; charset=UTF-8\r\n";


////ici on détermine l'expediteur et l'adresse de réponse
$headers .= "From: $nom <$mail>\r\nReply-to : $nom <$mail>\nX-Mailer:PHP";

$subject="Stage 2009";
$destinataire="moi@machin.fr";

$body="Stage 2009\nPrenom + Nom : $nom\nSociete : $societe\nPoste :
$poste\nAdresse : $adresse\nEmail : $email\nTelephone : $telephone" ;
mail($destinataire,$subject,$body,$headers);
include("merci.php");
}
else
{
//captcha faux
include("erreur.php");
}
}
?>

--
<|[;o)) METIS
http://www.graphM.com
Pour m'écrire en privé,
moi c'est metis15 et
je tourne à l'Oranges...

10 réponses

1 2 3 4 5
Avatar
Bruno Desthuilliers
METIS a écrit :
METIS wrote:
...
Le problème, c'est que les accents donnent...
Nathalie Mazé dans le champ De de l'email reçu



Petite question :
Est-ce que ça peut venir d'un réglage chez l'hébergeur ?
(C'est un petit site 60gp chez OVH de base, j'ai rien touché au niveau du
manager)

A priori non, il n'y a que dans la BdD qu'il y a un réglage éventuel de
l'encodage...




Non. Il y a les headers HTTP par défault envoyés par Apache, l'encodage
que tu déclares dans tes fichiers html et/ou php, l'encodage effectif
_de_ tes fichiers html et/ou php (si ton fichier est encodé en bidule et
que tu déclare via entête http qu'il est en bidule, forcément, ça va pas
le faire), l'encodage que tu déclares pour l'envoi du mail, et ce que
comprend le logiciel de mail qui reçoit...

Evidemment, si la chaine n'est pas cohérente, ça pose problème...
Avatar
METIS
Olivier Miakinen wrote:
...
D'après la suite des échanges, nous sommes dans le premier cas. Donc
ton fichier PHP est codé en Latin1 (ou en cp1252) et tes données
t'arrivent en UTF-8.

Les différentes possibilités que tu as sont donc :



Merci, c'est sympa de prendre un peu de temps pour mon cas.
Le problème est...
- Que je ne fais rien de spécial.
- Que ça marche en génral pour les gens...
- Que ça n'a pas l'air de marcher pour moi, sur 2 sites qui ne sont pas chez
le même hébergeur, l'un en France, l'autre dans les îles!!
C'est pour ça que je pensais à un problème d'encodage...
mais quand on a...
header('Content-Type: text/html; charset=UTF-8');
ou
header('Content-Type: text/html; charset=ISO-8859-1');
...il y en a bien 1 des 2 qui devrait marcher..?

D'autre part, je souhaite trouver un truc qui marche partout, avec des
réglages standards de base.
Outlook-E, site messagerie Orange, thunderB, etc.
Est-ce seulement possible

--
<|[;o)) METIS
http://www.graphM.com
Pour m'écrire en privé,
moi c'est metis15 et
je tourne à l'Oranges...
Avatar
METIS
Bruno Desthuilliers wrote:
METIS a écrit :
METIS wrote:
...
Le problème, c'est que les accents donnent...
Nathalie Mazé dans le champ De de l'email reçu



Petite question :
Est-ce que ça peut venir d'un réglage chez l'hébergeur ?
(C'est un petit site 60gp chez OVH de base, j'ai rien touché au
niveau du manager)

A priori non, il n'y a que dans la BdD qu'il y a un réglage éventuel
de l'encodage...




Non. Il y a les headers HTTP par défault envoyés par Apache,...



Hum...
Que ce soit pour lire sur la messagerie Orange, ou dans OE par exemple..?
Bon, j'ai farfouillé dnas le manager de OVH, je ne vois pas où on peut
changer quelque chose... Je n'ai rien touché de toute façon.

--
<|[;o)) METIS
http://www.graphM.com
Pour m'écrire en privé,
moi c'est metis15 et
je tourne à l'Oranges...
Avatar
Bruno Desthuilliers
METIS a écrit :
METIS wrote:
Bonjour,


[...]

J'ai avancé, tout seul comme un grand !!

J'ai tout simplement mis...
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
...dans le formulaire



Je suppose que tu veux dire "dans le fichier php ou html dans lequel se
trouve le formulaire" ?

(c'était resté en UTF-8, que j'avais dû mettre pour
des essais)



Le charset déclaré dans cette balise doit correspondre à l'encodage
effectivement utilisé pour enregistrer le fichier...
Avatar
METIS
METIS wrote:
Bonjour,


[...]

J'ai avancé, tout seul comme un grand !!

J'ai tout simplement mis...
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
...dans le formulaire (c'était resté en UTF-8, que j'avais dû mettre pour
des essais)
Du coup l'email arrive correctement :
Nom : é
Prénom : é
Email : test
Téléphone : test
Objet : test
Avec le champ De : é

Reste à régler le problème dans le site de messagerie Orange (par ex.), j'ai
ceci :
De : "é" <unspecified-domain>

Nom : ? (losange noir, avec ? blanc)
Pr?nom : ?
Email : test
T?l?phone : test
Objet : test

Comme les clients utilisent de + en + les messageries sur Internet plutôt
qu'un client messagerie, ça peut poser problème...

--
<|[;o)) METIS
http://www.graphM.com
Pour m'écrire en privé,
moi c'est metis15 et
je tourne à l'Oranges...
Avatar
METIS
"Bruno Desthuilliers" a écrit dans
le message de news: 493ed1bc$0$30923$
METIS a écrit :
J'ai avancé, tout seul comme un grand !! [...]
(c'était resté en UTF-8, que j'avais dû mettre pour
des essais)



Le charset déclaré dans cette balise doit correspondre à l'encodage
effectivement utilisé pour enregistrer le fichier...




Mais le problème n'est réglé qu'en partie...

--
<|[;o)) METIS
http://www.graphM.com
Pour m'écrire en privé,
moi c'est metis15 et
je tourne à l'Oranges...
Avatar
Olivier Miakinen
Le 09/12/2008 17:39, METIS a écrit :

Les différentes possibilités que tu as sont donc :



Merci, c'est sympa de prendre un peu de temps pour mon cas.
Le problème est...
- Que je ne fais rien de spécial.
- Que ça marche en génral pour les gens...
- Que ça n'a pas l'air de marcher pour moi, sur 2 sites qui ne sont pas chez
le même hébergeur, l'un en France, l'autre dans les îles!!



Le problème est que... je te livre trois solutions clé en main, chacune
des trois étant à même de résoudre ton problème, mais que tu les balayes
comme si tu t'en fichais.

C'est pour ça que je pensais à un problème d'encodage...



Ben oui, et même de mélange d'encodages (partie gauche en Latin1, partie
droite en UTF-8).

mais quand on a...
header('Content-Type: text/html; charset=UTF-8');
ou
header('Content-Type: text/html; charset=ISO-8859-1');
...il y en a bien 1 des 2 qui devrait marcher..?



Mais oui. Un cas fait marcher la partie gauche de tes lignes, l'autre la
partie droite.

D'autre part, je souhaite trouver un truc qui marche partout, avec des
réglages standards de base.



Merci de relire mon article, je te donne non pas UN mais TROIS trucs. Tu
choisis celui que tu veux, tous sont censés marcher.
Avatar
Olivier Miakinen
Le 09/12/2008 13:10, Bruno Desthuilliers a écrit :

[...]
j'en profite d'ailleurs pour le soumettre à la critique impitoyable de
ce groupe...):



Je vais me gêner... ;-)

<?php
function check_headers($headers)
{
// recherche des newlines, éventuellement suivis d'entêtes mails
$bad = "/(%0A|%0D|n+|r+)(content-type:|to:|cc:|bcc:)?/i";



Ah, il y a du boulot.

Tout d'abord, ton expression rationnelle n'étant pas ancrée à droite,
toute la deuxième parenthèse suivie de « ? » est parfaitement inutile :
tout ce qui sera reconnu avec sera aussi bien reconnu sans, et vice
versa. On peut donc la simplifier ainsi :

$bad = "/(%0A|%0D|n+|r+)/i";

Pour la même raison, les « + » derrière « n » et derrière « r » sont
tout aussi inutiles. Par ailleurs, je ne vois pas pourquoi laisser le
soin à PCRE de traduire n en saut de ligne et r en retour chariot,
alors qu'on peut le faire dès la lecture de la chaîne en écrivant "n"
et "r" au lieu de "r" et "n".

$bad = "/(%0A|%0D|n|r)/i";

Maintenant, je ne vois pas comment des caractères '%', puis '0', puis
'A' ou 'a' ou 'D' ou 'd', pourraient se transformer en sauts de ligne
dans la fonction d'envoi de courriel.

$bad = "/(n|r)/i";

Il ne reste plus qu'un choix entre deux caractères, ce qui se prète bien
à une classe de caractères. Et vu que ces deux caractères n'ont pas de
version majuscule ou minuscule on peut se passer de l'option /i.

$bad = "/[nr]/";

$is_suspect = FALSE;
$report = "";



Note que $is_suspect n'est pas absolument indispensable puisque, dans
tous les cas de figure, tu as en permanence la relation suivante :
$is_suspect === ($report !== "")
Cela dit, on peut le laisser pour améliorer la lisibilité du code.

foreach($headers as $header=>$value) {
if (preg_match($bad, $value) != 0) {



On en est à :

if (preg_match("/[nr]/", $value) != 0) {

Éventuellement, tu dois pouvoir remplacer ce test par l'un des deux
suivants, probablement plus rapides, mais c'est sans doute moins lisible
car les fonctions sont moins connues :

if (strpbrk($value, "nr") !== FALSE) {

ou :

if (strspn($value, "nr") > 0) {

[...]
// la plupart des navigateurs placent cet entête dans leur requête
// les scripts des spammeurs ne le font pas nécessairement...
if (empty($_SERVER['HTTP_USER_AGENT'])) {
$is_suspect = TRUE;
$report .= "empty user agent";
}



Bof bof bof... À mon avis, même si cela ne te faisait perdre qu'un
client sur mille du fait qu'il a configuré son navigateur pour ne pas
envoyer cet entête (ou parce qu'il passe par un proxy qui le vire),
le gain serait quand même négatif car ce test n'ajoute strictement rien
en terme de sécurité.

return $is_suspect ? $report : FALSE;
}



Équivalent à :

return $report ? $report : FALSE;

Et en fait, il suffirait probablement de faire :

return $report;

D'autant que tu le testes avec empty() et que $report ne sera jamais
« empty » lorsque $is_suspect est vrai.

// ton code ici
// ...

$nom = $_POST['nom'];
$mail = $_POST['mail'];

// lister ici tous les champs à vérifier...
$unsafe_headers = array("nom"=>$nom, "mail"=>$mail);
$spam_report = check_headers($unsafe_headers);
if (! empty($spam_report)) {
// soit logger le rapport, soit l'envoyer par mail à l'admin,
// soit les deux....



... et donc envoyer un mail avec des paramètres expéditeur, destinataire
et headers statiques, ce qu'on aurait pu faire dès le début. ;-)

[...]

Dernier point : on n'utilise *JAMAIS* directement la moindre variable
venant de l'extérieur - à moins bien sûr d'aimer se faire pirater d'une
façon ou d'une autre.



[OUI]
Avatar
Bruno Desthuilliers
Olivier Miakinen a écrit :
Le 09/12/2008 13:10, Bruno Desthuilliers a écrit :
[...]
j'en profite d'ailleurs pour le soumettre à la critique impitoyable de
ce groupe...):



Je vais me gêner... ;-)

<?php
function check_headers($headers)
{
// recherche des newlines, éventuellement suivis d'entêtes mails
$bad = "/(%0A|%0D|n+|r+)(content-type:|to:|cc:|bcc:)?/i";



Ah, il y a du boulot.




Probablement - j'avais hacké ça à la va-vite il y a quelques années à
partir d'un snippet trouvé ailleurs, après avoir appris par expérience
ce qu'était un header injection, et dans la mesure où ça fonctionne, je
n'y ai jamais retouché. N'ayant pas recodé de formulaire de contact en
PHP depuis, je n'ai jamais eu le besoin de remettre ça au propre. Mais
voilà qui est fait grâce à toi et pour l'édification des futurs lecteurs
de ce ng !-)

(snip améliorations).
Avatar
METIS
Olivier Miakinen wrote:

Le problème est que... je te livre trois solutions clé en main,
chacune des trois étant à même de résoudre ton problème, mais que tu
les balayes comme si tu t'en fichais.



Non, non, je ne balaye pas.
Je cherchais (maladroitement) à savoir si ces solutions sont du domaine
patch (ça déconne, on bidouille pour que ça marche) ou s'il y a un truc
général à faire pour que ça aille (compte tenu du fait que je comprends pas
toujours vos explications...(;o)).

Bon, déjà je me suis apperçu que je ne demandais pas la même chose côté
formulaire et côté fichier de traitement.
Le formulaire, durant tous mes essais était resté avec un balise META sur
UTF-8.
Re-bon, quand j'ai fait les essais du fichier de traitement avec header
UTF-8, ça marchait pas. Donc au moins j'ai des doutes sur l'enploi de UTF-8.

Excuse-moi et merci.


--
<|[;o)) METIS
http://www.graphM.com
Pour m'écrire en privé,
moi c'est metis15 et
je tourne à l'Oranges...
1 2 3 4 5