[Résolu] Accent sur un courriel généré par formulaire de contact

Bonjour,

J’ai créé sur mon site un formulaire de contact pour envoyer un courriel. Lorsque le courriel contient des accents dans l’objet ou le corps du message, le message reçu ne contient pas les caractères accentués mais des choses comme: “idée” au lieu de “idée”.

Je me suis dit que cela était sûrement en rapport avec une histoire d’encodage, et j’ai donc ajouté dans mon code les lignes suivantes avant d’envoyer le courriel:

$objet = utf8_encode($objet); $message = utf8_encode($message);

Mais cela n’a rien changé au problème. Quelqu’un aurait-il une idée ? Euh non … une idée !

D’avance merci pour vos lumières …

Hello,

Je verrais deux possibilités:

  • une déclaration pour l’encodage dans l’en-tête de la page, du genre

et de l’utf-8 de l’autre côté pour traiter les données du formulaire

  • ta page enregistrée avec un encodage non utf-8 (donc le navigateur va se baser là-dessus pour bien afficher les caractères); p.ex. quand j’enregistre un index.php avec gedit (GNU/Linux), je peux définir l’encodage, et si je ne mets pas de déclaration mais que j’enregistre en iso-8859, c’est cet encodage qui sera utilisé pour l’affichage

Tu peux aussi éventuellement vérifier avec quel encodage ta page apparaît correctement dans ton navigateur (dans Firefox: Affichage > Encodage des caractères): si les accents sont affichés correctement en utf-8, il faut harmoniser les définitions pour cet encodage…

Coop,
Greg

Merci Greg pour ta réponse,

J’ai fait les différentes vérifications dont tu parles.
Ma page de contact possède l’entête suivant (vérifié en affichant le code source sous Firefox):

Quand, sous Firefox, je consulte l’entête de réponse de ma page, j’obtiens:

[code]Server: Apache
X-Powered-By: PHP/5.4.11
Vary: User-Agent,Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=4, max=500
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

200 OK [/code]

Et sous Firefox, Affichage/Encodage des caractères, me dit Unicode(UTF-8).

Donc, je ne vois toujours pas où se situe mon problème …

Merci pour ton aide,
Thierry

Bonjour,

Peut-être ajouter dans les headers le code ci-dessous, à adapter en fonction de votre script, pour déclarer le mail lui-même en UTF-8.

$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers .= 'Content-Transfer-Encoding: 8bit' . "\r\n";

Cordialement,

Bonsoir Matthieu,

J’ai ajouté le code proposé dans mon script et … je ne reçois plus le message !
Après différents essais, il s’avère que c’est la dernière ligne de code proposée qui pose soucis.

Si je ne conserve que les deux premières lignes, je reçois encore le message, mais toujours sans les caractères accentués.

J’examinerai demain les traces fournies par le serveur pour mieux comprendre l’absence d’envoi du courriel.

En attendant, et à toutes fins utiles, je dépose ici le code du script utilisé (récupéré quelque part sur internet et adapté à ma situation).
Dans le code placé à la fin de ce message, j’ai juste modifié l’adresse du destinataire du courriel généré pour éviter les spams sur mon adresse.

Merci à vous pour le coup de main.
Thierry

PS: je viens de m’apercevoir que les messages reçus sans les accents (avec Thunderbird) possèdent dans leur entête le champ suivant:

J’imagine qu’il y a là une part de l’explication peut être …

[code]<?php

/*
********************************************************************************************
CONFIGURATION
********************************************************************************************
*/
// destinataire est votre adresse mail. Pour envoyer à plusieurs à la fois, séparez-les par une virgule
$destinataire = ‘bidon@bidon.fr’;

// copie ? (envoie une copie au visiteur)
$copie = ‘non’;

// Action du formulaire (si votre page a des paramètres dans l’URL)
// si cette page est index.php?page=contact alors mettez index.php?page=contact
// sinon, laissez vide
$form_action = ‘’;

// Messages de confirmation du mail
$message_envoye = “Votre message a bien été envoyé !”;
$message_non_envoye = “L’envoi du mel a échoué, veuillez réessayer SVP.”;

// Message d’erreur du formulaire
$message_formulaire_invalide = “Vérifiez que tous les champs soient bien remplis et que le mel soit sans erreur.”;

/*

  • NoSpamQuestion affiche une question pour la validation d’un formulaire …
  • $mode, mode question ou réponse par défaut tirage au sort de question {string}
  • $answer, lors de la demande d’une réponse à la question numero tant … {int}
  • @returns array
  • Ajouter une question :
  • copier/coller ces lignes et remplir le contenu entre guillemets doubles :
  • $array_pictures$j]‘num’] = $j; // ne pas changer cette ligne
  • $array_pictures$j]‘question’] = “mettre ici la question (correspondant à l’image si vous utilisez une image)”;
  • $array_pictures$j]‘answer’] = “mettre ici la réponse à l’énigme”;
  • $j++; // ne pas oublier cette ligne dans la copie :slight_smile:
  • C’est tout. Question suivante ? :slight_smile:

*/
function NoSpamQuestion($mode = ‘ask’, $answer = 0)
{
$array_pictures = array(); $j = 0;

$array_pictures$j]'num'] = $j;
$array_pictures$j]'question'] = "Quelle est la couleur du cheval blanc d'Henri IV (en cinq lettres)";
$array_pictures$j]'answer'] = "blanc";
$j++;

$array_pictures$j]'num'] = $j;
$array_pictures$j]'question'] = "Le soleil est-il chaud ou froid ?";
$array_pictures$j]'answer'] = "chaud";
$j++;

$array_pictures$j]'num'] = $j;
$array_pictures$j]'question'] = "Ecrire 12 en lettres";
$array_pictures$j]'answer'] = "douze";
$j++;

$array_pictures$j]'num'] = $j;
$array_pictures$j]'question'] = "Combien font 2+2 ? (en six lettres)";
$array_pictures$j]'answer'] = "quatre";
$j++;

$array_pictures$j]'num'] = $j;
$array_pictures$j]'question'] = "Quelle est la dernière lettre du mot; alternatif ?";
$array_pictures$j]'answer'] = "f";
$j++;

if ($mode != 'ans')
{
	// on est en mode 'tirer au sort', on tire une image aléatoire
	$lambda = rand(0, count($array_pictures)-1);
	return $array_pictures$lambda];
}
else
{
	// on demande une vraie réponse
	foreach($array_pictures as $i => $array)
	{
		if ($i == $answer)
		{
			return $array;
			break;
		};
	};
}; // Fin if ($mode != 'ans')

};
/*
********************************************************************************************
FIN DE LA CONFIGURATION
********************************************************************************************
*/
// on tire au sort une question
$nospam = NoSpamQuestion();

/*

  • cette fonction sert à nettoyer et enregistrer un texte
    */
    function Rec($text)
    {
    $text = htmlspecialchars(trim($text), ENT_QUOTES);
    if (1 === get_magic_quotes_gpc())
    {
    $text = stripslashes($text);
    }

    $text = nl2br($text);
    return $text;
    };

/*

  • Cette fonction sert à vérifier la syntaxe d’un email
    /
    function IsEmail($adresseMel)
    {
    $value = preg_match(’/^(?:\w!#$%&’*+-/=?^`{|}~]+.)
    \w!#$%&’*+-/=?^`{|}~]+@(?:(?:(?:a-zA-Z0-9_{0,61}[a-zA-Z0-9_-]?.)+a-zA-Z0-9_{0,61}[a-zA-Z0-9_]?)|(?:(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5]).){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])]))$/’, $adresseMel);
    return (($value === 0) || ($value === false)) ? false : true;
    }

// formulaire envoyé, on récupère tous les champs.
$nom = (isset($_POST’nom’])) ? Rec($_POST’nom’]) : ‘’;
$prenom = (isset($_POST’prenom’])) ? Rec($_POST’prenom’]) : ‘’;
$mel = (isset($_POST’mel’])) ? Rec($_POST’mel’]) : ‘’;
$telephone = (isset($_POST’telephone’])) ? Rec($_POST’telephone’]) : ‘’;
$objet = (isset($_POST’objet’])) ? Rec($_POST’objet’]) : ‘’;
$message = (isset($_POST’message’])) ? Rec($_POST’message’]) : ‘’;
$antispam_h = (isset($_POST’antispam_h’])) ? Rec($_POST’antispam_h’]) : ‘’;
$antispam_r = (isset($_POST’antispam_r’])) ? Rec($_POST’antispam_r’]) : ‘’;

// On va vérifier les variables et l’email …
$mel = (IsEmail($mel)) ? $mel : ‘’; // soit l’email est vide si erroné, soit il vaut l’email entré
$err_formulaire = false; // sert pour remplir le formulaire en cas d’erreur si besoin

if (isset($_POST’envoi’]))
{
// On demande la vraie réponse
$verif_nospam = NoSpamQuestion(‘ans’, $antispam_r);

if (strtolower($antispam_h) != strtolower($verif_nospam'answer']))
{
	// le formulaire s'arrête ici
	echo '<p class="messageErreurFormulaire">Vous n\'avez pas répondu correctement à la question Antispam ...</p>';
            $err_formulaire = true;
}
else
{
	if (($nom != '') && ($mel != '') && ($objet != '') && ($message != ''))
	{
		// on préfixe l'objet du message pour réperer qu'il a été envoyé via le site
                    $objet = '[panierbio47.fr] '.utf8_encode($objet);

		// les 4 variables sont remplies, on génère puis envoie le mail
		$headers  = 'From:'.$nom.' <'.$mel.'>' . "\r\n";

// $headers .= 'Reply-To: '.$mel. “\r\n” ;
$headers .= ‘MIME-Version: 1.0’ . “\r\n”;
$headers .= ‘Content-type: text/html; charset=UTF-8’ . “\r\n”;
$headers .= ‘Content-Transfer-Encoding: 8bit’ . “\r\n”;
//$headers .= ‘X-Mailer:PHP/’.phpversion();

		// envoyer une copie au visiteur ?
		if ($copie == 'oui')
		{
			$cible = $destinataire.','.$mel;
		}
		else
		{
			$cible = $destinataire;
		};

                    // Remplacement de certains caractères spéciaux
		$message = str_replace("'","'",$message);
		$message = str_replace("’","'",$message);
		$message = str_replace(""",'"',$message);
		$message = str_replace('<br>','',$message);
		$message = str_replace('<br />','',$message);
		$message = str_replace('<br/>','',$message);
		$message = str_replace("<","<",$message);
		$message = str_replace(">",">",$message);
		$message = str_replace("&","&",$message);
                    $message = utf8_encode($message);

		// Envoi du mail
		if (mail($cible, $objet, $message, $headers))
		{
			echo '<p>'.$message_envoye.' Cliquer <a href="coord.php">ici pour ré-afficher le formulaire</a></p>';
		}
		else
		{
			echo '<p class="messageErreurFormulaire">'.$message_non_envoye.'</p>';
                            $err_formulaire = true;
		};
	}
	else
	{
		// une des 3 variables (ou plus) est vide ...
		echo '<p class="messageErreurFormulaire">'.$message_formulaire_invalide.'</p>';
		$err_formulaire = true;
	};
};

}; // fin du if (!isset($_POST’envoi’]))

if (($err_formulaire) || (!isset($_POST’envoi’])))
{
// afficher le formulaire
echo ‘

Vos coordonnées

Nom*:

Prénom:

Adresse mel*:

Téléphone:



Votre message

Objet*:

Message*:’.stripslashes($message).‘



Validation du formulaire (pour éviter les robots spammeurs)

’.$nospam’question’].’*



Les champs suivis de * sont obligatoires.



';
};

?>
[/code]

Salut,

Voir avec le code suivant, normalement plus de problème avec les accents.

<?php
header('Content-Type: text/html; charset=utf-8');
/*
	********************************************************************************************
	CONFIGURATION
	********************************************************************************************
*/
// destinataire est votre adresse mail. Pour envoyer à plusieurs à la fois, séparez-les par une virgule
$destinataire = 'bidon@bidon.fr';

// copie ? (envoie une copie au visiteur)
$copie = 'non';

// Action du formulaire (si votre page a des paramètres dans l'URL)
// si cette page est index.php?page=contact alors mettez index.php?page=contact
// sinon, laissez vide
$form_action = '';

// Messages de confirmation du mail
$message_envoye = "Votre message a bien été envoyé !";
$message_non_envoye = "L'envoi du mel a échoué, veuillez réessayer SVP.";

// Message d'erreur du formulaire
$message_formulaire_invalide = "Vérifiez que tous les champs soient bien remplis et que le mel soit sans erreur.";

/*
 * NoSpamQuestion affiche une question pour la validation d'un formulaire ...
 * $mode, mode question ou réponse par défaut tirage au sort de question {string}
 * $answer, lors de la demande d'une réponse à la question numero tant ... {int}
 *
 * @returns array
 *
 * Ajouter une question :
 * copier/coller ces lignes et remplir le contenu entre guillemets doubles :
 *
 * $array_pictures$j]'num'] = $j; // ne pas changer cette ligne
 * $array_pictures$j]'question'] = "mettre ici la question (correspondant à l'image si vous utilisez une image)";
 * $array_pictures$j]'answer'] = "mettre ici la réponse à l'énigme";
 * $j++; // ne pas oublier cette ligne dans la copie :-)
 *
 * C'est tout. Question suivante ? :-)
 *
 */
function NoSpamQuestion($mode = 'ask', $answer = 0)
{
	$array_pictures = array(); $j = 0;

	$array_pictures$j]'num'] = $j;
	$array_pictures$j]'question'] = "Quelle est la couleur du cheval blanc d'Henri IV (en cinq lettres)";
	$array_pictures$j]'answer'] = "blanc";
	$j++;

	$array_pictures$j]'num'] = $j;
	$array_pictures$j]'question'] = "Le soleil est-il chaud ou froid ?";
	$array_pictures$j]'answer'] = "chaud";
	$j++;

	$array_pictures$j]'num'] = $j;
	$array_pictures$j]'question'] = "Ecrire 12 en lettres";
	$array_pictures$j]'answer'] = "douze";
	$j++;

	$array_pictures$j]'num'] = $j;
	$array_pictures$j]'question'] = "Combien font 2+2 ? (en six lettres)";
	$array_pictures$j]'answer'] = "quatre";
	$j++;

	$array_pictures$j]'num'] = $j;
	$array_pictures$j]'question'] = "Quelle est la dernière lettre du mot; alternatif ?";
	$array_pictures$j]'answer'] = "f";
	$j++;

	if ($mode != 'ans')
	{
		// on est en mode 'tirer au sort', on tire une image aléatoire
		$lambda = rand(0, count($array_pictures)-1);
		return $array_pictures$lambda];
	}
	else
	{
		// on demande une vraie réponse
		foreach($array_pictures as $i => $array)
		{
			if ($i == $answer)
			{
				return $array;
				break;
			};
		};
	}; // Fin if ($mode != 'ans')
};
/*
	********************************************************************************************
	FIN DE LA CONFIGURATION
	********************************************************************************************
*/
	// on tire au sort une question
	$nospam = NoSpamQuestion();

/*
 * cette fonction sert à nettoyer et enregistrer un texte
 */
function Rec($text)
{
	$text = htmlspecialchars(trim($text), ENT_QUOTES);
	if (1 === get_magic_quotes_gpc())
	{
		$text = stripslashes($text);
	}

	$text = nl2br($text);
	return $text;
};

/*
 * Cette fonction sert à vérifier la syntaxe d'un email
 */
function IsEmail($adresseMel)
{
	$value = preg_match('/^(?:\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $adresseMel);
	return (($value === 0) || ($value === false)) ? false : true;
}


// formulaire envoyé, on récupère tous les champs.
$nom        = (isset($_POST'nom']))        ? Rec($_POST'nom'])        : '';
$prenom     = (isset($_POST'prenom']))     ? Rec($_POST'prenom'])     : '';
$mel        = (isset($_POST'mel']))        ? Rec($_POST'mel'])        : '';
$telephone  = (isset($_POST'telephone']))  ? Rec($_POST'telephone'])  : '';
$objet      = (isset($_POST'objet']))      ? Rec($_POST'objet'])      : '';
$message    = (isset($_POST'message']))    ? Rec($_POST'message'])    : '';
$antispam_h = (isset($_POST'antispam_h'])) ? Rec($_POST'antispam_h']) : '';
$antispam_r = (isset($_POST'antispam_r'])) ? Rec($_POST'antispam_r']) : '';

// On va vérifier les variables et l'email ...
$mel = (IsEmail($mel)) ? $mel : ''; // soit l'email est vide si erroné, soit il vaut l'email entré
$err_formulaire = false; // sert pour remplir le formulaire en cas d'erreur si besoin

if (isset($_POST'envoi']))
{
	// On demande la vraie réponse
	$verif_nospam = NoSpamQuestion('ans', $antispam_r);

	if (strtolower($antispam_h) != strtolower($verif_nospam'answer']))
	{
		// le formulaire s'arrête ici
		echo '<p class="messageErreurFormulaire">Vous n\'avez pas répondu correctement à la question Antispam ...</p>';
                $err_formulaire = true;
	}
	else
	{
		if (($nom != '') && ($mel != '') && ($objet != '') && ($message != ''))
		{
			// on préfixe l'objet du message pour réperer qu'il a été envoyé via le site
			$objet = '[panierbio47.fr] '.$objet;

			// les 4 variables sont remplies, on génère puis envoie le mail
			$headers = 'MIME-Version: 1.0' . "\r\n";
			$headers .= 'Content-type: text/html; charset="UTF-8"' . "\r\n";
			$headers .= 'Content-Transfer-Encoding: 8bit' . "\r\n";
			$headers .= 'From:'.$nom.' <'.$mel.'>' . "\r\n";
			$headers .= 'Reply-To: '.$mel. "\r\n" ;
			$headers .= 'X-Mailer:PHP/'.phpversion();

			// envoyer une copie au visiteur ?
			if ($copie == 'oui')
			{
				$cible = $destinataire.','.$mel;
			}
			else
			{
				$cible = $destinataire;
			};

			// Envoi du mail
			if (mail($cible,  $objet, $message, $headers))
			{
				echo '<p>'.$message_envoye.' Cliquer <a href="coord.php">ici pour ré-afficher le formulaire</a></p>';
			}
			else
			{
				echo '<p class="messageErreurFormulaire">'.$message_non_envoye.'</p>';
                                $err_formulaire = true;
			};
		}
		else
		{
			// une des 3 variables (ou plus) est vide ...
			echo '<p class="messageErreurFormulaire">'.$message_formulaire_invalide.'</p>';
			$err_formulaire = true;
		};
	};
}; // fin du if (!isset($_POST'envoi']))

if (($err_formulaire) || (!isset($_POST'envoi'])))
{
	// afficher le formulaire
	echo '
		<form id="contact" method="post" action="'.$form_action.'">
			<fieldset><legend>Vos coordonnées</legend>
 	                        <p><label for="nom">Nom*:</label><input type="text" name="nom" id="nom" value="'.stripslashes($nom).'" tabindex="1" autofocus required /><br/>
        			<label for="prenom">Prénom:</label><input type="text" name="prenom" id="prenom" value="'.stripslashes($nom).'" tabindex="2" /><br/>
  				<label for="mel">Adresse mel*:</label><input type="email" name="mel" id="mel" tabindex="3" required /><br/>
 				<label for="telephone">Téléphone:</label><input type="tel" name="telephone" id="telephone" tabindex="4" /></p>
			</fieldset>
			<fieldset><legend>Votre message</legend>
                                <p><label for="objet">Objet*:</label><input type="text" id="objet" name="objet" value="'.stripslashes($objet).'" tabindex="5" required /><br/>
                                <label for="message">Message*:</label><textarea name="message" id="message" cols="70" rows="10" tabindex="6" required >'.stripslashes($message).'</textarea></p>
			</fieldset>
			<fieldset><legend>Validation du formulaire <span class="note">(pour éviter les robots spammeurs)</span></legend>
                                <p><label for="antispam_h">'.$nospam'question'].'*</label><input type="text" name="antispam_h" id="antispam_h" required /><input type="hidden" name="antispam_r" value="'.$nospam'num'].'"  /></p>
			</fieldset>
                        <p class="note">Les champs suivis de * sont obligatoires.</p>
			 <input class="aligncenter" type="submit" name="envoi" value="Envoyer votre message" />
		</form>';
};

?>

Bonjour Matthieu,

En utilisant ton code, je ne reçois plus mes messages, bien qu’à l’envoi aucune erreur ne soit détectée car le texte “Votre message a bien été envoyé” s’affiche à tous les coups.
J’ai consulté le fichier log d’hier sans trouver trace d’une erreur expliquant pourquoi je ne reçois pas le message; j’imagine que côté serveur, il n’y a pas eu d’erreur de détectée … ?

Pour recevoir à nouveau mes messages, je suis obligé de mettre en commentaire, les lignes suivantes:

// $headers .= 'Content-type: text/html; charset="UTF-8"' . "\r\n"; // $headers .= 'Content-Transfer-Encoding: 8bit' . "\r\n";

Dans ce cas, je reçois bien le message dont le champ objet est affiché correctement (ie avec les accents, on progresse donc !) bien que l’entête du message reçu comporte toujours le champ:

Par contre, le corps du message est toujours incorrectement affiché.

Pourquoi cette différence de comportement ? est-ce parce que objet est un champ de type input/text et message un champ de type textarea ?

J’avoue que je suis dubitatif …

Merci pour ton aide.

En text/plain visiblement ça passe mieux qu’avec text/html, mais je ne sais pas pourquoi…
Ci dessous les lignes 154 à 167 modifiées:

// on préfixe l'objet du message pour réperer qu'il a été envoyé via le site
$objet = '[panierbio47.fr] '.$objet;
// on encode des elements du header
//bousille l'affichage du mail mais supprime une erreur BAD HEADER dans les en têtes
//$objet= mb_encode_mimeheader($objet,"utf-8");
//$nom = mb_encode_mimeheader($nom, "utf-8");

// les 4 variables sont remplies, on génère puis envoie le mail
$headers = 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-type: text/plain; charset=utf-8' . "\n";
$headers .= 'Content-Transfer-Encoding: 8bit' . "\n";
$headers .= 'From:'.$nom.' <'.$mel.'>' . "\n";
$headers .= 'Reply-To: '.$mel. "\n" ;
$headers .= 'X-Mailer:PHP/'.phpversion();

J’ai bien le sujet et le corps du message avec les accents, mais toujours l’erreur “Non-encoded…”.
J’arrive à la supprimer en passant un coup “mb_encode_mimeheader”, mais alors les accents sont à nouveau illisibles.

Effectivement, je confirme ce que tu me dis.
Lorsque je l’enlève le commentaire sur les mb_encode_mimeheader, l’erreur disparaît de l’entête du message, mais les accents disparaissent …

Concernant le corps du message, ça fonctionne également en utilisant text/plain.
Donc le problème est résolu, et tant pis pour l’entête du message !

Merci infiniment pour ton aide sans laquelle je n’aurais pas pu résoudre ce problème !