Bonjour,

J'ai un serveur xampp et je voudrais créer un site en utf8, qui me semble être un format plus standard, notamment pour pouvoir utiliser AJAX sans complication.

Le résultat que j'obtiens : Les caractères accentués s'affichent correctement si ils proviennent d'une variable ou s'ils sont écrits directement, ma page html étant lue par le navigateur en utf-8, mais toutes les informations provenant de la base de donnée affichent des � à la place des caractères accentués.
Si je force mon navigateur à lire la page html en iso-8859, les données provenant de la base de donnée s'affichent correctement mais pour le reste les caractères accentuées deviennent é.

Voilà ce qui me fait dire qu'une partie de ma page est en utf8 (celle que je fais directement), et l'autre partie est en iso (celle qui vient de mysql).

Petite précision : dans phpmyadmin tout s'affiche normalement à l'écran sans problème d'accents.


Voici ce que j'ai déjà tenté pour résoudre mon problème :

J'ai ajouté la ligne AddDefaultCharset utf8 à mon ficher de configuration apache.

Dans phpmyadmin, j'ai bien Jeu de caractères pour MySQL: UTF-8 Unicode (utf8) et Interclassement pour la connexion MySQL: utf8_general_ci

J'ai vérifié que je n'avais aucun champs, table, ou base de donnée réglé sur autre chose que utf8_general_ci, et même créé une nouvelle base au cas où.

J'enregistre mes fichiers .php avec l'encodage utf8 (d'ailleurs les éléments qui ne viennent pas de la base de donnée s'affichent correctement dans le navigateur)

J'ai indiqué <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

J'ai essayé d'ajouter header( 'content-type: text/html; charset=utf-8' ); au début de mes fichiers php, mais je ne crois pas de toute façon qu'il soit utile de le faire si j'ai déjà indiqué AddDefaultCharset utf8 dans le fichier de configuration apache?

J'ai essayé également d'ajouter une requête SET NAMES "utf8" au début de mon fichier php, mais je ne suis pas sure d'avoir bien compris si c'est là qu'il fallait l'ajouter, de plus il ne me semble pas non plus utile de le faire si la communication avec mysql est déjà définie en utf8.

J'ai même lu les fichiers de config php apache et mysql à la recherche d'une petite option à dé-commenter ou modifier, sans succès.


La seule chose qui "fonctionne" est d'utiliser la fonction utf8_encode de façon systématique sur les données provenant de ma bdd, mais je ne trouve vraiment pas ça élégant, c'est comme guérir le symptôme mais pas la maladie.

Si quelqu'un peut voir ce qui ne va pas là dedans, ce que j'aurais du faire ou ne pas faire, cela m'aiderait beaucoup car je sèche depuis un moment sur ce problème et ce que j'ai pu lire ici et là ne m'a pas été d'un grand secours.

Merci d'avance.
Agnès
Modifié par MAgnes (16 Nov 2011 - 12:28)
Comment tu te connectes à mysql et comment tu mets ton SET NAMES utf8 ? (envoi le code)
MAgnes a écrit :
J'ai essayé d'ajouter header( 'content-type: text/html; charset=utf-8' ); au début de mes fichiers php, mais je ne crois pas de toute façon qu'il soit utile de le faire si j'ai déjà indiqué AddDefaultCharset utf8 dans le fichier de configuration apache?

Ce n'est effectivement pas nécessaire, Apache ajoutant l'information de charset à l'en-tête Content-Type quand tu utilises la directive AddDefaultCharset. Tu peux le vérifier en regardant les en-têtes HTTP de tes pages (avec la console web de Firefox, avec les onglets Net ou Ressources de Firebug, Web Inspector, Opera Dragonfly ou les Developer Tools d'IE).

MAgnes a écrit :
J'ai essayé également d'ajouter une requête SET NAMES "utf8" au début de mon fichier php, mais je ne suis pas sure d'avoir bien compris si c'est là qu'il fallait l'ajouter, de plus il ne me semble pas non plus utile de le faire si la communication avec mysql est déjà définie en utf8.

Quelques précisions:

- SET NAMES "utf8" est une requête MySQL. C'est donc une commande qu'un client MySQL (par exemple un script PHP) va soumettre à un serveur MySQL (en l'occurrence le serveur MySQL est une des briques logicielles de ton serveur MAMP, et il répond aux requêtes envoyées par des clients divers).

- Ce n'est pas une instruction PHP. Si tu veux envoyer cette requête depuis ton code PHP, il faut utiliser une fonction PHP permettant d'envoyer une requête MySQL (au pif, je dirais que la fonction [i]mysql_query()
permet de faire ça, mais je n'y connais pas grand chose).

- S'il y a un client MySQL (ton script PHP) et un serveur MySQL (le... euh... le serveur MySQL quoi!), il y a forcément une connexion entre ce client et ce serveur. Et, par défaut, les connexions MySQL sont en ISO-8859-1 (aussi appelé "latin1" par MySQL), sauf si tu as explicitement changé la configuration globale de ton serveur MySQL. Tes données sont apparemment toutes marquées comme étant en UTF-8. La connexion est, par défaut, en ISO-8859-1. Quand tu récupères tes données marquées en UTF-8 avec une connexion en ISO-8859-1, MySQL va transcoder tes données à la volée de UTF-8 vers ISO-8859-1 avant de te les retourner. Donc tu reçois des données en ISO-8859-1. La solution: déclarer que ta connexion est en UTF-8 (c'est-à-dire que tu attends des données en UTF-8, et que si tu envoies des données elles seront en UTF-8), avec SET NAMES.

Il me semble que tu as les idées plutôt claires sur les questions de codage de caractères, le dernier bout de puzzle qui te manquait c'est cette histoire de connexion MySQL et de transcodage à la volée (pas étonnant, c'est pas intuitif...). Donc, pour corriger ton problème, il te faut utiliser SET NAMES mais avec la bonne syntaxe et au bon endroit.
- Pour la bonne syntaxe: voir la doc PHP à ce sujet, peut-être? Apparemment à partir de PHP5 on peut utiliser http://php.net/manual/en/function.mysql-set-charset.phpmysql_set_charset()[/i], et la doc recommande cette fonction plutôt qu'une requête MySQL avec SET NAMES.
- Pour le placement: a priori juste après avoir ouvert ta connexion MySQL.
Modifié par fvsch (10 Nov 2011 - 01:25)
J'avais effectivement passé la requête SET NAMES au serveur mysql par la commande mysql_query(). J'ai essayé de la mettre à plusieurs endroits : avant d'appeler la base de donnée ou après.
Je viens de comprendre pourquoi ça n'avait pas marché : j'utilise PDO, donc il ne comprenait pas le mysql_query(). Pour cette même raison il n'a pas compris le mysql_set_charset que tu m'as conseillé.
C'est d'essayer ça qui m'a mise sur la voie car il me renvoyait un message d'erreur indiquant que ma variable $bdd (qui correspond à ma connection à mysql) n'était pas correcte.

Il semblerait que SET NAMES n'est pas obsolète lorsqu'elle est utilisée avec PDO. Je n'ai pas eu le temps de vérifier dans la doc PHP que cette info est juste, mais elle semble faire l'unanimité des quelques posts que j'ai trouvé sur le sujet. Je vous dirai lorsque j'aurai vérifié.

En tout cas, ça marche. 2 solutions possibles :
1) inscrire la commande SET NAMES directement dans les options pdo :

$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES \'UTF8\'';
$bdd=new PDO('mysql:host=localhost;dbname=MaBase', 'user', 'motdepasse', $pdo_options);


2) faire une requête SET NAMES juste après la connection à la bdd avec la syntaxe pdo à la place de mysql_query():

$bdd=new PDO('mysql:host=localhost;dbname=MaBase', 'user', 'motdepasse', $pdo_options);
$bdd->query('SET NAMES utf8');



J'ai commencé dès le départ avec PDO sans trop me poser de question (c'était conseillé dans le tuto que j'ai utilisé), donc je n'avais même pas pensé à ça dans la résolution de mon problème....


Je vais quand même m'assurer que c'est tout bien sécurisé d'utiliser cette combinaison PDO / SET NAMES avant de me lancer dans la conception complète du site.


Merci beaucoup pour l'aide rapide et efficace.

Agnès
Modifié par MAgnes (10 Nov 2011 - 13:12)
Après vérification dans le manuel PHP, c'est bien ainsi qu'il faut procéder. Je marque donc le sujet résolu. Merci encore de m'avoir aidée.