[Résolu] MySQL fait-il du véritable UTF-8 ?

HTML5, CSS3, Javascript, support des mobiles... Que penser de votre site ? Vous manquez d'informations pour la construction d'un site qui puisse s'afficher correctement partout ? C'est un problème simple, un peu complexe ? Venez ici !
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

[Résolu] MySQL fait-il du véritable UTF-8 ?

Message par GizMecano »

Hello,

Continuant une conversion au format UTF-8, je me heurte à un nouveau problème qui me fait grandement m'interroger sur l'aptitude de MySQL à gérer ce format d'affichage correctement.

J'ai créé une base et une table avec l'interclassement utf8_general_ci. J'y stocke des données sorties de NotePad ++ au format UTF-8, sans BOM. Dans MySQL, l'affichage est nickel : c'est normal, vous me direz, je suis en fr-utf-8.

Je bidouille ma requête en PHP pour sortir les données de la table en question, en vlan : revoilà ces satanés caractères � et compagnie... :cry:

Je vérifie mon en-tête :

Code : Tout sélectionner

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Pas d'erreur, visiblement, surtout que le reste des textes sortis de scripts PHP est lui nickel.

Bon, j'ai essayé plusieurs autres formats de conversion, avec BOM, sans BOM, en copiant le texte ANSI, en changeant l'interclassement. Rien à faire... :cry:

Passablement énervé, je me résous à utiliser le magique :

Code : Tout sélectionner

echo utf8_encode
Merveilleux, ça marche : sauf que je n'ai plus une seule apostrophe, tout le texte s'agglutinant lamentablement.

Là, je sèche. Quelqu'un serait-il assez charitable pour me filer une piste :?:
Dernière modification par GizMecano le 27 août 2005, 11:34, modifié 1 fois.
GizMecano.net
http://gizmecano.net
Bobe
Iguane
Messages : 742
Inscription : 28 juil. 2003, 21:29

Message par Bobe »

Quel est le charset de la connexion à la base de données ?
« La vie d’un geek est un combat perpétuel contre l’imperfection »
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

Message par GizMecano »

Bobe a écrit :Quel est le charset de la connexion à la base de données ?
Excellente question : où je le trouve :?:
GizMecano.net
http://gizmecano.net
Bobe
Iguane
Messages : 742
Inscription : 28 juil. 2003, 21:29

Message par Bobe »

Essaie avec la requète : SHOW VARIABLES
La variable qui t’interesse est "character_set_connection"
« La vie d’un geek est un combat perpétuel contre l’imperfection »
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

Message par GizMecano »

Hello,
Bobe a écrit :Essaie avec la requète : SHOW VARIABLES
La variable qui t’interesse est "character_set_connection"
D'accord, alors dans ce cas, la variable en question semble bonne. Cependant, je remarque que quelques autres variables qui concernent le serveur semblent ne pas être en UTF-8 :
  • character_set_client :arrow: utf8
    character_set_connection :arrow: utf8
    character_set_database :arrow: utf8
    character_set_results :arrow: utf8
    character_set_server :arrow: latin1
    character_set_system :arrow: utf8
    collation_connection :arrow: utf8_general_ci
    collation_database :arrow: utf8_general_ci
    collation_server :arrow: latin1_swedish_ci
Est-ce que l'erreur peut venir de là :?:
Si oui, comment puis-je modifier ces variables :?:
Ne seront-elles modifiées que pour cette base ou pour toutes les bases que j'ai en locale :?:
Et, tant qu'à faire, comment être certain que je n'ai pas le même problème avec le serveur distant quand je mettrais ça en ligne :?:

D'avance merci.

Ciao,
GizMecano.net
http://gizmecano.net
Bobe
Iguane
Messages : 742
Inscription : 28 juil. 2003, 21:29

Message par Bobe »

Mhh, les quelques connaissances que j’ai de ce sujet viennent du fait que j’ai été confronté au même problème il y a quelques temps.

N’ayant pas réussi à modifier le charset de la connexion en php (Utiliser mysqli_set_charset() me donne "Call to undefined function mysqli_set_charset()" avec PHP 5.0.4), j’ai tout laissé sur latin1 et mis mes données en utf-8 dans la base (comme je n’utilise pas de fonctions SQL de traitement de chaîne particulières qui nécessiteraient le support des caractères multi-octets, ce n’est pas génant).

[après recherche google]

J’ai trouvé ça:
http://dev.mysql.com/doc/mysql/fr/chars ... ction.html
« La vie d’un geek est un combat perpétuel contre l’imperfection »
calimo
Animal mythique
Messages : 14118
Inscription : 26 déc. 2003, 11:51

Re: MySQL fait-il du véritable UTF-8 ?

Message par calimo »

GizMecano a écrit :Je vérifie mon en-tête :

Code : Tout sélectionner

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Ce n'est pas une entête, simplement une balise meta... vérifie les entêtes HTTP (p.ex avec LiveHTTPHeaders), ou au moins que l'encodage soit le bon dans les propriétés de la page.

Je rappelle que pour déterminer l'encodage, la priorité est donnée aux entêtes HTTP en premier, puis s'il n'y en a pas au prologue XML pour du XML, et en dernier seulement s'il n'y a rien d'autre à la balise meta (c'est le cas lors des consultations en local file://).

Tu pourrais peut-être aussi vérifier de ce côté-ci à tous hasards... :wink:
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

Message par GizMecano »

Hello,
Bobe a écrit :N’ayant pas réussi à modifier le charset de la connexion en php (...), j’ai tout laissé sur latin1 et mis mes données en utf-8 dans la base (...).
Ben, c'est pas rassurant comme réponse :?
J'espère bien trouver une solution un jour, tout de même. Parce que je me vois mal jongler entre les deux solutions...

Bobe a écrit :J’ai trouvé ça:
http://dev.mysql.com/doc/mysql/fr/chars ... ction.html
Je vais aller voir ça.

Calimo a écrit :Vérifie les entêtes HTTP (p.ex avec LiveHTTPHeaders), ou au moins que l'encodage soit le bon dans les propriétés de la page
Cette extension ne me donne rien, mais alors rien du tout. Tous les onglets sont vides... :?

En revanche, les en-têtes donnés par Web Developer sont :

Code : Tout sélectionner

Server: Apache/1.3.33 (Win32) PHP/4.3.10
X-Powered-By: PHP/4.3.10
Set-Cookie: langue=fr; expires=Sat, 24-Sep-2005 16:12:37 GMT
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
Encodage chunked : qu'est-ce que c'est que ce truc encore :?:

La fenêtre d'informations sur la page me répond :

:arrow: Encodage : UTF-8

Donc, ça semble ok de ce côté, non :?:

D'autres pistes, avant que je n'aille tenter de bidouiller la configuration à l'aide de l'adresse de Bobe :?:

Merci.

Ciao,
GizMecano.net
http://gizmecano.net
Bobe
Iguane
Messages : 742
Inscription : 28 juil. 2003, 21:29

Message par Bobe »

Avec ça, c’est bon:

Code : Tout sélectionner

mysqli_query('SET character_set_client = utf8');
mysqli_query('SET character_set_connection = utf8');
mysqli_query('SET character_set_results = utf8');
C’est avec character_set_results qu’on obtient enfin les données en utf-8.
Les deux autres doivent sùrement être utiles également, mais je ne sais pas encore en quoi (je soupçonne que ça serve pour les cas d'insertion ou mise à jour). phpMyAdmin les positionne sur utf8 en tout cas.

edit: /vient de relire la page qu’il a lui-même linké.

Raccourci au lieu des trois requètes plus haut:

Code : Tout sélectionner

mysqli_query("SET NAMES 'utf8'");
« La vie d’un geek est un combat perpétuel contre l’imperfection »
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

Message par GizMecano »

Hello,
Bobe a écrit :Avec ça, c’est bon
Hélas, je pense que j'ai un problème. C'est même pire qu'avant :cry:

Une deuxième colonne (valeurs globales), que je n'avais pas vue, a fait son apparition, et malgré plusieurs manipulations, tant avec ton aide que celle de la page indiquée, les variables restent les mêmes, voire pire, certaines sont revenues à en latin (je les souligne ci-dessous) :
  • character set client :arrow: utf8 :arrow: latin1
    character set connection :arrow: utf8 :arrow: latin1
    character set database :arrow: latin1 :arrow: latin1
    character set results :arrow: utf8 :arrow: latin1
    character set server :arrow: latin1 :arrow: latin1
    character set system :arrow: utf8 :arrow: utf8
    collation connection :arrow: utf8_general_ci :arrow: latin1_swedish_ci
    collation database :arrow: latin1_swedish_ci :arrow: latin1_swedish_ci
    collation server :arrow: latin1_swedish_ci :arrow: latin1_swedish_ci
J'ai retenté la manipulation plusieurs fois, je n'ai aucun message d'erreur mais les variables... ne varient justement pas d'un poil.

Je ne comprends rien, à ces histoires de valeurs pour la session et de valeurs globales : je saisis du texte en utf-8 et je veux qu'il sorte en utf-8, ça devrait quand même pas être compliqué :evil:

Merci encore de votre aide. Ca finira bien par marcher...

Ciao,
GizMecano.net
http://gizmecano.net
calimo
Animal mythique
Messages : 14118
Inscription : 26 déc. 2003, 11:51

Message par calimo »

Remarque, si tu as tout en latin1, tu peux y entrer de l'utf-8 en le faisant passer pour de l'iso, et à la sortie c'est toujours de l'utf-8, il me semble que rien ne devrait être modifié... simplement stocké dans la base dans un format pas parfaitement compréhensible... (je dis ça, mais je n'ai jamais essayé).
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

Message par GizMecano »

Hello,
calimo a écrit :Remarque, si tu as tout en latin1, tu peux y entrer de l'utf-8 en le faisant passer pour de l'iso
Comment :?: Parce que là, même en saisissant en utf-8, j'ai toujours une bonne cuvée de �...

Merci,

Ciao,
GizMecano.net
http://gizmecano.net
Bobe
Iguane
Messages : 742
Inscription : 28 juil. 2003, 21:29

Message par Bobe »

GizMecano a écrit : Une deuxième colonne (valeurs globales), que je n'avais pas vue, a fait son apparition, et malgré plusieurs manipulations, tant avec ton aide que celle de la page indiquée, les variables restent les mêmes, voire pire, certaines sont revenues à en latin (je les souligne ci-dessous) :
C’est normal ça.
Je ne comprends rien, à ces histoires de valeurs pour la session et de valeurs globales : je saisis du texte en utf-8 et je veux qu'il sorte en utf-8, ça devrait quand même pas être compliqué :evil:
Les valeurs globales, ce sont les valeurs par défaut dans MySQL. Les valeurs de session, ce sont les valeurs actives pour la connexion considérée, donc là, ce que tu vois, ce sont les réglages pour la connexion que créé phpmyadmin. Ça n’a pas d’importance pour toi, ce qui t’interesse, ce sont les réglages de ta connexion que tu créés dans tes scripts php. Et dans ce cas, il faut que tu exécutes la requètes SET NAMES que j’ai donnée plus haut pour bosser en utf-8 avec mysql (ou alors tu lui files à bouffer du texte en latin1 mais ça réduit grandement l’intérêt).

donc dans tes scripts, tu créés ta connexion, puis tu fais mysqli_query("SET NAMES 'utf8'");

Ensuite, mysql t’enverra de l’utf-8 (même de colonnes étant en latin1). MySQL considèrera aussi ce que tu lui envoies comme étant de l’utf-8. Pour qu’il le laisse en utf-8 et ne fasse pas de conversion vers latin1 par exemple, assure toi que les interclassements de tes colonnes sont bien sur utf8_general_ci (ou tout autre valeur en utf8_*).

Tout ce que je te dis là est le fruit de ma réflexion sur le problème, non un retour d’expérience, mais je pense que ça doit être ça.

Le mieux est que tu créés une table de test ayant utf8_general_ci comme interclassement, tu y créés deux champs, id en auto incrément et texte en varchar ou text (l’interclassement de la colonne texte devrait être le même que celui de la table, si ce n’est pas le cas, met le manuellement sur utf8_general_ci ou n’importe quel autre interclassement en utf8_*)

Ensuite, un script de test:

Code : Tout sélectionner

<?php
/* le script doit être en utf-8 (pour les données de la requète insert, ou sinon, fais un utf8_encode() sur les données avant de les insérer */
$db = new mysqli('localhost', 'user', 'pass', 'dbname');

/* Vérification de la connexion */
if (mysqli_connect_errno()) {
   printf("Echec de la connexion : %s\n", mysqli_connect_error());
   exit;
}

$db->query("SET NAMES 'utf8'");

$db->query("INSERT INTO table_test (texte) VALUES('Ceci est un test de la gestion de l\'utf-8 par MySQL é è € à ß')");

$result = $db->query("SELECT texte FROM table_test LIMIT 1");
$row = $result->fetch_array();

header('Content-Type: text/plain; charset=UTF-8');
echo $row['texte'];
exit;

?>
Le texte doit être affiché correctement (donc utf-8 valide), et quand tu regardes dans phpmyadmin, il doit être affiché correctement aussi. Si ces deux conditions sont réunies, c’est que c’est bon normalement.

Edit: Chez moi, le test est passé, je sors bien de l’utf-8 et c’est bien de l’utf-8 qui est stocké dans la table.
« La vie d’un geek est un combat perpétuel contre l’imperfection »
Invité

Message par Invité »

Hello,

Tout d'abord, Bobe, un grand merci. Je crois que j'ai enfin réussi à comprendre le truc, mais hélas, je dois dire que ce n'est pas tout à fait avec l'aide de ton fichier de test. En effet, alors que j'ai strictement suivi pas à pas ton message et recopier ton code, voilà ce que j'obtiens :
Firefox a écrit :Fatal error: Cannot instantiate non-existent class: mysqli in c:\program files\easyphp\www\test\index.php on line 3
Cependant, et bien que j'avoue que mes connaissances en PHP ne semblent pas du tout avoir les mêmes bases que les tiennes (j'ai mis un moment à comprendre comment tu codais ça), j'ai réussi a insérer visiblement au bon endroit la fameuse requête permettant de renvoyer en utf-8. En tout cas, ça fonctionne enfin quand je tape :

Code : Tout sélectionner

	$recherche=mysql_query ("SET NAMES 'utf8'");
	$recherche=mysql_query ("SELECT num,txt FROM base ORDER BY num DESC LIMIT 1")
		or die (PbRequete);
Je ne sais pas si c'est très orthodoxe, mais ça fonctionne sans erreur.

Bon, prochaine étape, essayer de comprendre à quoi sert réellement cette fonction header() que tu places en fin de code, là où je me contentais d'une balise meta, comme le signalait naguère Calimo.

Ciao,

PS : En passant, comment tu obtiens de véritable apostrophe dans tes messages sur le forum ?
GizMecano
Lézard à collerette
Messages : 416
Inscription : 02 août 2004, 20:27

Message par GizMecano »

C'est normal, j'aime pas les cookies :oops:
GizMecano.net
http://gizmecano.net
Répondre

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 3 invités