Demande de précision sur encodage UTF8 et base de données [Résolu/Fermé]

Signaler
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
-
 Utilisateur anonyme -
Bonjour,

J'ai lu et relu les tutos disponibles sur le net sur l'encodage de caractères, et je pense avoir compris.

J'ai par contre un comportement de ma base de données bien incompréhensible.

La bdd est en UFT8. Mes scripts sont tous pourvus d'un header adéquat indiquant UTF8. header( 'content-type: text/html; charset=utf-8' );

dans le fichier .htacces, j'ai bien php_flag default_charset utf-8.

Lorsque j'écris dans ma base de données par l'intermédiaire d'un script, j'ai des caractères indésirables type : Marie-thérèse qui sont écrits dans la bdd.

Par contre, si je lis la base de données, tout est normal, le texte récupéré est bien Marie-Thérèse.

Cela n'affecte pas la marche de l'ensemble, mais pour la rigueur de programmation, j'aimerai bien que quelqu'un puisse m'expliquer.

D'avance merci.

16 réponses


Bonjour

Il ne suffit pas que ta base de donnée soit en UTF-8, il faut exécuter la requête "SET NAMES 'utf8'" lors de la connexion.
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Bonjour et merci de ta réponse.

J'ai essayé :
$bdd = new PDO('mysql:host=XXXXX.fr.mysql;dbname=YYYYY', 'lionsclubannona', 'ZZZZZ',$pdo_options,array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
(syntaxe PDO lue sur un tuto)

cela ne marche malheureusement pas mieux !..

Perso j'utilise array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET NAMES utf8")
Ça ne doit pas changer grand chose.
Le problème viendrait donc d'ailleurs. Utilises-tu les fonctions utf8_encode et utf8_decode dans tes scripts ?
Messages postés
36637
Date d'inscription
mercredi 5 novembre 2003
Statut
Modérateur
Dernière intervention
11 juillet 2020
3 315
Salut

les scripts sont il eux même encodé en UTF8 ?
Utilisateur anonyme
J'y ai pensé mais son type d'affichage correspond plutôt à des données UTF8 affichées dans une page déclarée en ISO qq chose.
Or sa page est bien déclarée - si son header marche - en UTF8.
Ce qui me fait penser à une autre question pour janmar :

As-tu une balise meta avec un charset différent dans ta page ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Bonjour,

Je n'ai que la balise meta normale
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
plus :
$bdd = new PDO('mysql:host=XXXXX.fr.mysql;dbname=YYYYY', 'ZZZ', 'ZZZZZ',$pdo_options,array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));

De plus, tous mes scripts sont encodés en UTF8 avec le logiciel TextWrangler :
caractères: Central european (Mac OS)
Use UTF-8 for Unix script I/O

Je n'utilise pas les fonctions uft8_encode , ni uft8_decode.
Si tes scripts n'étaient pas en utf8, tu aurais des problèmes d'affichage, mais pas Marie-thérèse. Tu aurais plutôt Marie-th?r?se.

Le Marie-thérèse, tu le vois avec PHPMyAdmin ou avec un script ?
Et tu l'as enregistré comment : avec PHPMyAdmin ou avec un script ? Avec "Marie-Thérèse" En dur dans le script, ou saisi via un formulaire ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Le Marie-thérèse, je le vois avec PHPMyAdmin directement dans la table.
Je l'ai envoyé par un formulaire dans lequel il y a bien le header en début du script.
<form method="post" action="inscrire.php">
<label for="prenom">Prénom :&nbsp;&nbsp;</label>

je saisis : Marie-Thérèse.
Lors de la connexion, j'ai bien le 'SET NAMES \'UTF8\' (dans le PDO).

Question complémentaire : la base est en utf8, je suppose que toutes les tables aussi....

Peut-on voir le script qui traite le formulaire ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Voilà le code

<?php
	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
	$bdd = new PDO('mysql:host=XXXX.fr.mysql;dbname=YYYY', 'ZZZZ', 'TTTT',$pdo_options,array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
	//mysql_set_charset("utf8");
if($_POST['action'] == 'Enregistrer') {
	$nom = htmlspecialchars($_POST['nom']);
	$nom = strtoupper($nom);
	$prenom = htmlspecialchars($_POST['prenom']);
	$prenom = str_replace(' ','-',$prenom);
	$prenom = strtolower($prenom);
	$prenom = ucfirst($prenom);
	$prenomnom = $prenom.' '.$nom;
	$adresse = htmlspecialchars($_POST['adresse']);
	$cp = htmlspecialchars($_POST['cp']);
	$ville = htmlspecialchars($_POST['ville']);
	
	$req = $bdd->prepare('INSERT INTO identite (Nom,Prenom,Adresse,CP,Ville) VALUES(:Nom,:Prenom,:Adresse,:CP,:Ville)');
				$req->execute(array(
				'Nom' => $nom,
				'Prenom' => $prenom,
				'Adresse' => $adresse,
				'CP' => $cp,
				'Ville' => $ville
				));
				
				$req = $bdd->prepare('INSERT INTO benevoles (nom) VALUES(:nom)');
				$req->execute(array(
				'nom' => $prenomnom
				));
			
				echo '<strong>Bénévole enregistré';?><br><br>
				&nbsp;&nbsp;&nbsp;&nbsp;<a href="saisie.html" target = "_blank">continuer</a></strong><?php
}
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Oui, je vois Marie-thérèse avec PHPMyAdmin directement dans la table.
Je l'ai enregistré avec un formulaire qui a en entete
header( 'content-type: text/html; charset=utf-8' );
<form method="post" action="inscrire.php">
<label for="prenom">Prénom :&nbsp;&nbsp;</label>
<INPUT type="text" name="prenom" size = 20 autofocus required />

et je saisis : Marie-Thérèse dans mon formulaire.
la page de réception a elle aussi le header ci-dessus et dans la connexion à la bdd, j'ai bien 'SET NAMES \'UTF8\'

Peut-on voir le script qui traite (qui reçoit) le formulaire ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Voilà le code

<?php
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$bdd = new PDO('mysql:host=XXXX.fr.mysql;dbname=YYYY', 'ZZZZ', 'TTTT',$pdo_options,array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
//mysql_set_charset("utf8");
if($_POST['action'] == 'Enregistrer') {
$nom = htmlspecialchars($_POST['nom']);
$nom = strtoupper($nom);
$prenom = htmlspecialchars($_POST['prenom']);
$prenom = str_replace(' ','-',$prenom);
$prenom = strtolower($prenom);
$prenom = ucfirst($prenom);
$prenomnom = $prenom.' '.$nom;
$adresse = htmlspecialchars($_POST['adresse']);
$cp = htmlspecialchars($_POST['cp']);
$ville = htmlspecialchars($_POST['ville']);

$req = $bdd->prepare('INSERT INTO identite (Nom,Prenom,Adresse,CP,Ville) VALUES(:Nom,:Prenom,:Adresse,:CP,:Ville)');
$req->execute(array(
'Nom' => $nom,
'Prenom' => $prenom,
'Adresse' => $adresse,
'CP' => $cp,
'Ville' => $ville
));

$req = $bdd->prepare('INSERT INTO benevoles (nom) VALUES(:nom)');
$req->execute(array(
'nom' => $prenomnom
));

echo '<strong>Bénévole enregistré';?><br><br>
    <a href="saisie.html" target = "_blank">continuer</a></strong><?php
}
Messages postés
1227
Date d'inscription
lundi 28 mars 2011
Statut
Membre
Dernière intervention
2 septembre 2013
71
Salut !

Ca m'est arrivé et j'ai utilisé utf8_decode et encode et problème résolu, mais ca peut être chiant si ton site/application n'as pas juste quelques lignes de code ...
Utilisateur anonyme
utf8_decode permet juste de cacher le vrai problème. Si tout est fait correctement, on n'en a pas besoin.

On l'avait sous les yeux depuis le début :
$bdd = new PDO('mysql:host=XXXXX.fr.mysql;dbname=YYYYY', 'lionsclubannona', 'ZZZZZ',$pdo_options,array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'')); 


Tu as un paramètre en trop dans ton new PDO, ce qui fait que le SET NAMES... est ignoré.
Supprime le "$pdo_option" et écris :
$bdd = new PDO('mysql:host=XXXXX.fr.mysql;dbname=YYYYY', 'lionsclubannona', 'ZZZZZ',array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'')); 
$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Utilisateur anonyme
Autre remarque, sans rapport avec ton problème : ce n'est pas une bonne idée d'utiliser htmlspecialchars avant d'enregistrer les données dans la base. Cette fonction est inutile pour la base de données, et modifie le contenu puisqu'elle remplace par exemple les < par des &lt;. Donc elle fausse les tris et recherches de mysql par la suite.
htmlspecialchars n'est utile qu'au moment de l'affichage.
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Bonsoir,
Je rentre juste de voyage, ce qui explique mon silence cette semaine.
Je te remercie de tes réponses qui , je pense, vont régler les problèmes.
1°) je n'imaginais pas que $_PDO_options mettait la pagaille.
2°) je crois que tu as vu juste avec htmlspecialchars, qui doit coder en iso lasti xxx.
Je teste tout ça et je te tiens au courant, mais je crois qu'on tient le bon bout.
encore merci.
Marc
Utilisateur anonyme
De rien.

En ce qui concerne htmlspecialchars, il suppose a priori que le texte est encodé en utf8 dans les versions récentes de php. Dans des versions plus anciennes, je crois bien que l'encodage par défaut était un iso_qqchose.
Dans tous les cas, tu peux mettre un paramètre pour obliger à prendre le bon encodage.
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
malheureusement, malgré tous les conseils de chacun, j'obtiens toujours : Marie-hélène dans ma base de données.
J'ai enlevé $pdo_options dans la connexion,
J'ai enlevé les htmlspecialchars dans le formulaire de réception,
J'ai aussi essayé de nommer explicitement le codage dans la variable :
$nom = strtoupper($_POST['nom'], 'UTF-8');
J'ai rajouté array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET NAMES utf8") dans la connexion.
J'ai vérifié que la base est bien en UTF-8_general_ci
Toutes mes tables sont aussi en UTF-8_general_ci

et l'enregistrement est toujours le même : Marie-hélène

Je commence à perdre mon latin (ou plutôt ce qu'il en reste !...)
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Je pense à une chose :
Je saisis mes variables dans des input tel que :
<form accept-charset="utf-8" method="post" action="inscrire.php">

<label for="prenom">Prénom :&nbsp;&nbsp;</label>
<INPUT type="text" name="prenom" size = 20 autofocus required />
</form>


l'input est-il bien envoyé en UTF-8 de cette manière ?

Bonsoir

Le accept-charset="utf-8" est inutile : par défaut, l'ncodage utilisé dans un formulaire est celui du document HTML. Si tu vois Marie-hélÃ, c'est très probablement que tu as bien de l'utf8 au niveau de ta page HTML, mais que c'est traité comme de l'isoqqchose par la base de données.

Je suppose qu'il y a encore quelque chose dans le code de la connexion ou dans les manipulations des données entre la réception et l'insertion dans la base. Peux-tu redonner ton code ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Merci de ta réponse. Je reprends mes scripts un par un :
Formulaire de saisie :
<?php
session_start();
header( 'content-type: text/html; charset=utf-8' );
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<title>saisie bénévoles</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href= "planning.css" />
</head>

<body>
<?php
echo'Saisissez un nouveau bénévole';?>
<form accept-charset="utf-8" method="post" action="inscrire.php">
<label for="prenom">Prénom :&nbsp;&nbsp;</label>
<INPUT type="text" name="prenom" size = 20 autofocus required />
<br />
<label for="nom">Nom :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<INPUT type="text" name="nom" size = 20 required/>
<br /><br>

<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT type="submit" value="Vérifier" />       <INPUT type="reset" value="Effacer" /></strong> 
___________________________________________
</form>


Voilà pour la saisie :

Maintenant, pour la réception du formulaire :
<?php
session_start();
header( 'content-type: text/html; charset=utf-8' );
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<title>reponse saisie</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href= "planning.css" />
</head>

<body>
<?php
	$bdd = new PDO('mysql:host=lXXXX.fr.mysql;dbname=YYYY', 'ZZZZ', 'TTTT',array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
	$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if($_POST['action'] == 'Enregistrer') {
	$nom = $_POST['nom'];
	$nom = strtoupper($nom, 'UTF-8');
	$prenom = $_POST['prenom'];
	$prenom = str_replace(' ','-',$prenom);
	$prenom = strtolower($prenom, 'UTF-8');
	$prenom = ucfirst($prenom, 'UTF-8');
	$prenomnom = $prenom.' '.$nom;
	$adresse = $_POST['adresse'];
	$cp = $_POST['cp'];
	$ville = $_POST['ville'];
	
	$req = $bdd->prepare('INSERT INTO identite (Nom,Prenom,Adresse,CP,Ville) VALUES(:Nom,:Prenom,:Adresse,:CP,:Ville)');
				$req->execute(array(
				'Nom' => $nom,
				'Prenom' => $prenom,
				'Adresse' => $adresse,
				'CP' => $cp,
				'Ville' => $ville
				));
				
				$req = $bdd->prepare('INSERT INTO benevoles (nom) VALUES(:nom)');
				$req->execute(array(
				'nom' => $prenomnom
				));
			
				echo '<strong>Bénévole enregistré';?><br><br>
				&nbsp;&nbsp;&nbsp;&nbsp;<a href="saisie.html" target = "_blank">continuer</a></strong><?php
}

			if (isset($_POST['prenom']))
			{
			$prenom = $_POST['prenom'];
			$prenom = str_replace(' ','-',$prenom);
			$prenom = strtolower($prenom);
			$prenom = ucfirst($prenom,'UTF-8');
			}else{ 
			echo 'Il manque le prénom';
			}
			
			if (isset($_POST['nom']))
			{
			$nom = $_POST['nom'];
			$nom = strtoupper($nom,'UTF-8');
			}else{ echo 'Il manque le nom';
			}
			
			$prenomnom = $prenom.' '.$nom;
			
// Vérification de l'existence du bénévole

			$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
			$bdd = new PDO('mysql:host=XXXXX.fr.mysql;dbname=YYYYY', 'ZZZZZ', 'TTTTT', array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
			$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			$reponse = $bdd->query("SELECT * FROM identite WHERE Nom = '$nom' AND Prenom = '$prenom' ");
			$donnees = $reponse->fetch();
			if (!empty($donnees['Nom']) AND !empty($donnees['Prenom']))
			{ 
				?><strong><?php
				echo $prenomnom.' existe déjà et habite :';?><strong/><br><?php
				echo $donnees['Adresse'].'<br>'.$donnees['CP'].' '.$donnees['Ville'];?><br><br><?php
				echo 'Voulez-vous néanmoins créer un homonyme ?<br>';
				
				// Affichage du formulaire
				
				echo '<form method="post">';
				
				?><label for="nom">Nom : </label><?php echo '<input class = "nom2" type="text" name="nom" required><br>';
				?><label for="nom">Prénom : </label><?php echo '<input class = "nom2" type="text" name="prenom" required><br>';
				?><label for="nom">Adresse : </label><?php echo '<input class = "nom2" type="text" name="adresse" required><br>'; 
				?><label for="nom">CP : </label><?php echo '<input class = "nom2" type="text" name="cp" required><br>';
				?><label for="nom">Ville : </label><?php echo '<input class = "nom2" type="text" name="ville" required><br><br>';
				echo '<input class = "nom2" type="submit" name="action" value="Enregistrer"></form>';
			
			}else{
				$req = $bdd->prepare('INSERT INTO identite (Nom,Prenom) VALUES(:Nom,:Prenom)');
				$req->execute(array(
				'Nom' => $nom,
				'Prenom' => $prenom
				));
				
				$req = $bdd->prepare('INSERT INTO benevoles (nom) VALUES(:nom)');
				$req->execute(array(
				'nom' => $prenomnom
				));
			
				echo '<strong>Bénévole enregistré';?><br><br>
				&nbsp;&nbsp;&nbsp;&nbsp;<a href="saisie.html" target = "_blank">continuer</a></strong>
				<?php
			}

			?>
			
			
</body>

Je n'arrive pas à faire marcher ton code car il y a des erreurs dedans.
Entre autres :
$nom = strtoupper($nom, 'UTF-8');
$prenom = ucfirst($prenom, 'UTF-8');

Mais les fonctions strtoupper et ucfirst n'admettent qu'un seul paramètre.
Quelle version de PHP as-tu pour que ça marche ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Version 5.3.27
D'après la doc (tu as suivi les liens ?) et mes essais, ça devrait planter et tu ne devrais rien enregistrer du tout.

Peux-tu faire un echo $prenom; juste après le $prenom = ucfirst($prenom, 'UTF-8'); pour voir ce que ça donne ?
Messages postés
148
Date d'inscription
vendredi 17 mai 2013
Statut
Membre
Dernière intervention
29 août 2015
3
Bonjour,
Tout d'abord, je te prie de bien vouloir m'excuser de tout le travail de recherche que je t'ai imposé, mais j'ai trouvé une anomalie que je n'avais pas vue, et qui me mettait le bazar depuis quelques jours : mon logiciel de FTP renommait mes fichiers au lieu de les remplacer sur mon site, ce qui fait que malgré les modifs, c'était toujours le même code qui s'exécutait. Je suis confus !...
Bon, après avoir tout repris, et enlevé les arguments en trop qui déclenchent bien une erreur, je constate :
l'écho $prenom indique bien Marie-Hélène.
L'enregistrement dans la base de données se fait bien sous Marie-Hélène.
Après avoir rajouté array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'')
lors de la connexion pour la lecture des infos, je lis normalement bien la table.

Il semble donc que le problème soit entièrement résolu.

Merci de ton aide précieuse.

Marc
Utilisateur anonyme
De rien

Au plaisir