accents et caractères spéciaux ne s'affichent

humantarget
Invité n'ayant pas de compte PHPfrance

09 sept. 2009, 18:33

Bonjour,

Pour ma page perso, j'essaie de mettre en place un formulaire de contact simple (nom, mail, sujet et message). Mais voilà, si l'envoie du message se passe bien, le nom et le mail du destinataire ainsi que le sujet ne s'affichent pas correctement dans ma boite mail.

Exemple de texte rentré dans le formulaire :
Nom : Père Noël
Mail : [email protected]
Sujet : Pommes & Scoubidous
Message : Une esperluette & entre \"guillemets doubles\" ou \'guillemets simples\'. attention aux chevrons < >.

Je sais, c'est bidon mais bon, je teste :wink:

Maintenant, voilà ce qui est affiché dans ma boite mail (Yahoo! pour ne pas la citer)
From : "P&[email protected]" <P&[email protected]>
Subject : Pommes & Scoubidous
Message : Une esperluette & entre \"guillemets doubles\" ou \'guillemets simples\'. attention aux chevrons < >.

D'où peut venir le problème ? Sachant que :
Je suis codé en utf-8 (<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />)
L'encodage de Php-MySql est sur utf-8 unicode ci (ainsi que l'interclassement)
Le code html qui crée le formulaire est le suivant
<p class="vert">Par E-mail :</p>
				<form method="post" action="mail.php">
	   				<p>
	   				<label for="nom">Nom Prénom</label><br/>
	   				<input type="text" id="nom" name="nom" tabindex="1"/><br/><br/>
	   				<label for="email">E-mail</label><br/>
	   				<input type="text" id="email" name="email" tabindex="2"/><br/><br/>
	   				<label for="sujet">Sujet</label><br/>
	   				<input type="text" id="sujet" name="sujet" tabindex="3"/><br/><br/>
	   				<label for="requete">Message</label><br/>
	   				<textarea id="message" name="message" rows="4" cols="40" tabindex="4"></textarea><br/>
	   				</p>
	   				<p>
	   				<input type="submit" value="Envoyer" tabindex="5"/>
	   				<input type="reset" value="Annuler" tabindex="6"/>
	   				</p>
	 			</form>
Le script qui envoie le mail est le suivant
<?php
					
					// récupération des valeurs rentrées dans les champs du formulaire
										
					$nom=htmlentities($_POST['nom']);
					$email=htmlentities($_POST['email']);
					$sujet=htmlentities($_POST['sujet']);
					$message=htmlentities($_POST['message']);
					
					// coupe le message en lignes de 70 caractères max
					$message=wordwrap($message, 70); 
					$destinataire='[email protected]';
					
					$headers  = 'MIME-Version: 1.0' . "\r\n";
					$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
					$headers .= 'From: '.$nom.' <'. $email.' >' . "\r\n";

					mail($destinataire, $sujet, $message, $headers);
					
					unset($nom, $email, $sujet, $message, $headers) ;
					header('Location: merci.php');
				?>
Merci pour votre aide parce que là, je sèche... :(

Eléphanteau du PHP | 27 Messages

09 sept. 2009, 19:54

Lorsque tu récupères et affiche les données récupérées dans ta page php (avant d'envoyer un mail), pas de problèmes d'encodage?

Et au passage ton apache est bien en utf8?

Plus d'infos ici: http://blog.neovov.com/index.php?2007/0 ... e-en-utf-8

ViPHP
AB
ViPHP | 5818 Messages

10 sept. 2009, 04:14

Le script qui envoie le mail est le suivant
<?php
					
					// récupération des valeurs rentrées dans les champs du formulaire
										
					$nom=htmlentities($_POST['nom']);
					$email=htmlentities($_POST['email']);
					$sujet=htmlentities($_POST['sujet']);
					$message=htmlentities($_POST['message']);
					
					// coupe le message en lignes de 70 caractères max
					$message=wordwrap($message, 70); 
					$destinataire='[email protected]';
					
					$headers  = 'MIME-Version: 1.0' . "\r\n";
					$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
					$headers .= 'From: '.$nom.' <'. $email.' >' . "\r\n";

					mail($destinataire, $sujet, $message, $headers);
					
					unset($nom, $email, $sujet, $message, $headers) ;
					header('Location: merci.php');
				?>
Tu ne dois pas utiliser htmlentities. Cela sert pour protéger l'affichage des données mais ici tu ne les affiche pas, tu les envoie dans un header. Il suffit juste de protéger les champs "nom" et "adresse mail" pour qu'on ne puisse pas se servir de ton formulaire comme boite à spam.
//...
function Protege_header($value) 
		{
			$value = str_replace("\n", "", str_replace("\r", "", $value));
			return $value;
		}

		$nom=Protege_header($_POST['nom']);
		$email=Protege_header($_POST['email']);
		$sujet=$_POST['sujet'];
		$message=$_POST['message'];
// etc.

Mammouth du PHP | 985 Messages

10 sept. 2009, 08:43

htmlentities possède des paramètres qui sont souvent oubliés. Moi même au départ je ne m'en étais pas aperçu, j'utilisais inutilement la fonction utf8_decode avec htmlentities...
Un de ces paramètres permet de configurer htmlentities suivant l'encodage utilisé, ISO-8859-1 étant utilisé par défaut...
Tout est expliqué dans le manuel: http://fr.php.net/htmlentities
Donc concrètement, si tu fais , par exemple, ceci:
//...
$message = htmlentities($_POST['message'], ENT_COMPAT, 'UTF-8');
//...
PS, un autre élément:
htmlentities est utile surtout au moment de l'affichage des données, donc il est souvent plus Safe d'utiliser cette fonction juste au moment de l'affichage des données et non dès la déclaration des variables, mais ça c'est juste mon avis personnel...


PS 2: ( Mais dans ton cas, ce n'est pas apparemment le soucis )
Les balises métas ne sont pas prioritaires au sujet de l'encodage des pages...
C'est à dire que si le serveur envoie un autre encodage dans les headers, la balise méta sera souvent ignorée...
Pour être certain que ce problème n'arrive jamais, il est pratique de modifier, par exemple, le header, comme ceci:
header('Content-Type: text/html; charset=UTF-8');
Cette ligne doit être mise à la première ligne de tes pages pour éviter un erreur de header déjà envoyé...[/i]
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

humantarget
Invité n'ayant pas de compte PHPfrance

10 sept. 2009, 14:46

Lorsque tu récupères et affiche les données récupérées dans ta page php (avant d'envoyer un mail), pas de problèmes d'encodage?

Et au passage ton apache est bien en utf8?

Plus d'infos ici: http://blog.neovov.com/index.php?2007/0 ... e-en-utf-8
1) j'ai modifié ma page mail.php pour qu'elle affiche ce que l'utilisateur a envoyé :
<p>
				Nom : <?php echo $_POST['nom']; ?><br/>
				E-mail : <?php echo $_POST['email']; ?><br/>
				Sujet : <?php echo $_POST['sujet']; ?><br/>
				Message : <?php echo $_POST['message']; ?><br/>
				</p>
Là, pas de problème : les accents, les caractères spéciaux etc s'affichent correctement. Donc, il semble que le problème vient lors de l'envoi des données.

2) Comment je peux savoir si mon serveur Apache est en utf-8 ?

3) Comme suggéré, si je fais ça :
Donc concrètement, si tu fais , par exemple, ceci:
//...
$message = htmlentities($_POST['message'], ENT_COMPAT, 'UTF-8');
//...
Je n'obtiens rien : toujours un problème de caractères.

Pour info, j'ai regarder les en-t^tes des mails reçus via ce formulaire, il y a cette ligne dedans :
Content-type: text/html; charset=iso-8859-15

Avez vous une autre solution ?

Merci !

Mammouth du PHP | 985 Messages

10 sept. 2009, 14:56

[EDIT]
voir plus bas
Modifié en dernier par Dr@ke le 10 sept. 2009, 16:06, modifié 1 fois.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Eléphant du PHP | 369 Messages

10 sept. 2009, 15:14

Salut,
Bonjour,
Pour ma page perso, j'essaie de mettre en place un formulaire de contact simple (nom, mail, sujet et message). Mais voilà, si l'envoie du message se passe bien, le nom et le mail du destinataire ainsi que le sujet ne s'affichent pas correctement dans ma boite mail.
Exemple de texte rentré dans le formulaire :
Nom : Père Noël
Mail : [email protected]
Sujet : Pommes & Scoubidous
Message : Une esperluette & entre \"guillemets doubles\" ou \'guillemets simples\'. attention aux chevrons < >.
Je sais, c'est bidon mais bon, je teste :wink:
Maintenant, voilà ce qui est affiché dans ma boite mail (Yahoo! pour ne pas la citer)
From : "P&[email protected]" <P&Atilde@servhome.org>
Subject : Pommes & Scoubidous
Message : Une esperluette & entre \"guillemets doubles\" ou \'guillemets simples\'. attention aux chevrons < >.
D'où peut venir le problème ? Sachant que :
Je suis codé en utf-8 (<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />)
L'encodage de Php-MySql est sur utf-8 unicode ci (ainsi que l'interclassement)
Le code html qui crée le formulaire est le suivant
[...]
Ca ressemble à de la double conversion. N'aurais-tu pas, avant ce code ci, une conversion déja présente?
Tu arrives à &Atilde@ en passant par é ce qui me fait dire que c'est ce type de problème.

Ca expliquerait ton soucis.

@+ bon code ;)

EDIT: essai d'intégrer le charset dans la balise form... Il me semble que tu l'as pas mise, on sait jamais ;)
<form method="post" action="mail.php" name="???" enctype="???" accept-charset="utf-8" >
Modifié en dernier par FuZZyLine le 10 sept. 2009, 15:28, modifié 1 fois.

Mammouth du PHP | 985 Messages

10 sept. 2009, 15:23

En effet, je n'avais pas tout lu, c'est de la double conversion, donc faut enlever les htmlentities car ta boite mail fait elle-même la conversion apperemment....

Mais il faut t'en assurer ensuite, en regardant la source du message:
Affichage -> Code source de la page -> et vérifier si les caractères sont convertis (exemple: é devient &eacute;)

[EDIT]
En fait AB avait déjà répondu.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

humantarget
Invité n'ayant pas de compte PHPfrance

10 sept. 2009, 16:04

Je ne suis pas sûr de bien comprendre
Mais il faut t'en assurer ensuite, en regardant la source du message:
Affichage -> Code source de la page -> et vérifier si les caractères sont convertis (exemple: é devient &eacute;)
Je veux bien modifié mail.php par le code que tu propose mais comment je fais pour regarder la source du message ? De plus, de quel message parle tu ? Celui sur ma boite mail ? Ou la page généré lors de l'envoie du mail... ?

Mammouth du PHP | 985 Messages

10 sept. 2009, 16:15

En fait comme l'expliquait AB, htmlentities est principalement utilisé lors de l'affichage des données.
Ici c'est donc ta boite mail qui affiche le message.
Donc il faut enlever les htmlentities de ton script d'envoi de mail.
Ensuite par sécurité, mais surement pas indispensable, tu peux vérifier si les caractères sont bien convertis dans ta boite mail.
Donc une fois dans ta boite mail, ouvre le message test que tu as envoyé et vérifie si les caractères sont convertis correctement dans la source du message: exemple les è deviendront des &eacute;.
Il est presque certain que tout est ok, mais c'est une bonne habitude a prendre avec ses scripts Php...
Et aussi une bonne façon de comprendre le fonctionnement de htmlentities.
Avec Firefox:
Menu en haut -> Affichage -> Affichage du code source
Avec Internet Explorer:
Menu en haut -> Affichage -> Source

[EDIT]
Donc concrètement, remplacer cette partie du code:
$regex_head = '/[\n\r]/';
$nom = trim(preg_replace($regex_head, '', $_POST['nom']));
$email = trim(preg_replace($regex_head, '', $_POST['email']));
$sujet = trim($_POST['sujet']);
$message = $_POST['message'];
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
AB
ViPHP | 5818 Messages

10 sept. 2009, 19:44

En fait comme l'expliquait AB, htmlentities est principalement utilisé lors de l'affichage des données.
Ici c'est donc ta boite mail qui affiche le message.
Donc il faut enlever les htmlentities de ton script d'envoi de mail.
Ensuite par sécurité, mais surement pas indispensable, tu peux vérifier si les caractères sont bien convertis dans ta boite mail.
Donc une fois dans ta boite mail, ouvre le message test que tu as envoyé et vérifie si les caractères sont convertis correctement dans la source du message: exemple les è deviendront des &eacute;.
Il est presque certain que tout est ok, mais c'est une bonne habitude a prendre avec ses scripts Php...
Et aussi une bonne façon de comprendre le fonctionnement de htmlentities.
Ou là c'est l'embrouille cette histoire. S'il supprime htmlentities (ce qu'il faut faire et que j'ai déjà indiqué dans mon premier post), il ne risque pas de voir des caractères convertis.

Et puis quand on travaille en UTF-8 on préconise d'utiliser htmlspecialchars() pour l'affichage des variables plutôt que htmlentities(), et dans ce cas pas besoin de spécifier le charset dans la fonction.
D'ailleurs si tu affiche le code source de cette page tu verras que les éèà etc. ne sont pas transformés mais écrit tel quel dans le code source.

Cela dit pour ce qui concerne son code pas besoin d'utiliser ni l'une ni l'autre de ces fonctions puisqu'elles servent à se protéger de l'injection de code lors de l'affichage de variables transmises par les visiteurs et qu'en l'occurrence dans son script il ne fait rien afficher mais transmet simplement ces variables.


Ensuite tant qu'a donné un lien vers un tuto sur l' UTF-8, il y en a un ici que j'ai voulu rendre accessible pour les débutants tout en étant néanmoins assez complet.


[EDIT]
Donc concrètement, remplacer cette partie du code:
$regex_head = '/[\n\r]/';
$nom = trim(preg_replace($regex_head, '', $_POST['nom']));
$email = trim(preg_replace($regex_head, '', $_POST['email']));
$sujet = trim($_POST['sujet']);
$message = $_POST['message'];
Ce qui revient donc au même que ce que j'avais indiqué initialement. Tu as ajouté trim en plus ce qui est une bonne idée mais alors pourquoi ne l'avoir pas fait également sur le message. Enfin bon avec ou sans trim ce n'était pas ça la cause du problème de l'affichage des caractères : il y avait au moins htmlentities qu'il fallait supprimer.

Alors humantarget ça avance ?

Mammouth du PHP | 985 Messages

10 sept. 2009, 19:51

Oui oui je sais AB, je l'ai dis que tu avais répondu à la question après avoir lu tous les messages attentivement...
Je n'aime pas les copiés collé, donc j'ai fais différemment, car je ne pouvais lui donner le script non sécurisé...
Donc je n'ai pas eu le choix de faire le minimum...
je précise juste que si c'était mon script, je ferais différemment, je pense que la sécurité ici est au minimum mais acceptable...
Ou là c'est l'embrouille cette histoire. S'il supprime htmlentities (ce qu'il faut faire et que j'ai déjà indiqué dans mon premier post), il ne risque pas de voir des caractères convertis.
Non non, rassure toi, aucune embrouille. La seule chose qui explique l'affichage en clair de caractères comme &Atilde est qu'il y a double conversion, la première dans son script Php et la deuxième dans sa boite mail.
En enlevant donc le htmlentities de son script, les caractères seront donc convertis normalement par sa boite mail...
Et puis quand on travaille en UTF-8 on préconise d'utiliser htmlspecialchars() pour l'affichage des variables plutôt que htmlentities(), et dans ce cas pas besoin de spécifier le charset dans la fonction.
Je ne suis pas de cet avis...
C'est juste que la majorité des gens ne connaissent pas le paramétrage de htmlentities en UTF-8 et donc ne cherchent pas a comprendre et utilisent htmlspecialchars().
J'explique tout dans mon premier Post, et c'est aussi expliqué dans le manuel PHP...

PS: Bref, ne prend pas mal ma réponse, en effet tu avais quasiment répondu avant mon premier message, je l'ai vue ensuite et surtout j'ai vue ensuite le problème de double conversion...
Modifié en dernier par Dr@ke le 10 sept. 2009, 22:06, modifié 2 fois.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
AB
ViPHP | 5818 Messages

10 sept. 2009, 22:03

[EDIT]
Juste une question:
function Protege_header($value) 
		{
			$value = str_replace("\n", "", str_replace("\r", "", $value));
			return $value;
		}
Es tu certain de la syntaxe: "\r" et "\n" ?
Je n'ai pas testé mais l'impression qu'un simple quote serait plus efficace, mais je me trompe peut-être.
Tu aurais dû tester, effectivement tu te trompe, cela n'aurait pas fonctionné.

Et puis quand on travaille en UTF-8 on préconise d'utiliser htmlspecialchars() pour l'affichage des variables plutôt que htmlentities(), et dans ce cas pas besoin de spécifier le charset dans la fonction.
Entièrement Faux !
C'est juste que la majorité des gens ne connaissent pas le paramétrage de htmlentities en UTF-8 et donc ne cherchent pas a comprendre et utilisent htmlspecialchars().
J'explique tout dans mon premier Post, et c'est aussi expliqué dans le manuel PHP...
Merci de nous expliquer que si on utilise généralement pas htmlentities() quand on code en UTF-8 c'est qu'on a pas lu le manuel. Vraiment trop fort :mrgreen:
Et si tu te posais la question de savoir pourquoi on dit certaines choses plutôt que de croire que si tu ne comprends pas en première lecture, c'est qu'on raconte n'importe quoi... c'est pas en option dans ton catalogue ?

Mammouth du PHP | 985 Messages

10 sept. 2009, 22:10

Lol j'avais viré mon commentaire sur ta fonction.
MAis comme tu me dis que je me trompe :wink:
"\r" et "\n" sont exécutés entre les doubles quotes, donc il va remplacer quoi?
Merci de nous expliquer que si on utilise généralement pas htmlentities() quand on code en UTF-8 c'est qu'on a pas lu le manuel. Vraiment trop fort :mrgreen:
J'ose le dire oui, et je l'affirme même... essaye dont de convertir 'à', 'é', 'è', dans une page encodée en UTF-8 avec htmlspecialchars() -> tu risques d'avoir des surprises...

Sinon pour le reste de ton message: bien je fais des erreurs aussi, jamais dis le contraire :wink:
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
AB
ViPHP | 5818 Messages

11 sept. 2009, 01:22

Lol j'avais viré mon commentaire sur ta fonction.
MAis comme tu me dis que je me trompe :wink:
"\r" et "\n" sont exécutés entre les doubles quotes, donc il va remplacer quoi?
Le plus simple c'est d'essayer avec les double quote et avec les simples quotes et tu verras la différence. Dans le premier cas ça fonctionne et pas dans le second. C'est une particularité de \n, \r en tant que code interprété, sinon avec des simples quotes ils seraient pris comme une chaîne de caractère et la recherche porteraient sur des \n ou \r que tu aurais inscrit directement dans ton message et non pas comme des retours ligne.

Cela dit les chaines de caractère "standard" peuvent être mises indifféremment entre double quote ou simple quote. Simplement entre 'simple quote' php ne va pas essayer d'interpréter le code donc c'est un pouième (non signifcatif) plus rapide. En fait on les utilise principalement pour des raisons de lisibilité, accessoirement pour des raisons de rigueur du code, et exceptionnellement comme dans l'exemple ci-dessus on doit utiliser des doubles quotes.
Merci de nous expliquer que si on utilise généralement pas htmlentities() quand on code en UTF-8 c'est qu'on a pas lu le manuel. Vraiment trop fort :mrgreen:
J'ose le dire oui, et je l'affirme même... essaye dont de convertir 'à', 'é', 'è', dans une page encodée en UTF-8 avec htmlspecialchars() -> tu risques d'avoir des surprises...
Je n'aurai pas de surprises car il n'y a aucun intérêt à convertir les caractères accentués dans une page codée en UTF-8. Donc sauf exception (je vois pas laquelle pour un usage courant) pourquoi faire ?