Problème encodage UTF-8

Discussion dans 'Problèmes de référencement spécifiques à vos sites' créé par noren, 4 Octobre 2013.

  1. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Bonsoir

    Voilou pour mes nouveaux projets je souhaites partir sur de l'UTF-8, mais voilà je m'embrouilles et je galères réellement.

    1) j'ai créé ma base, mes tables et chaque champs text en UTF8_general_CI

    2) j'ajoute ceci au début de mes pages html :

    Code:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    3) Je met également ceci dans mon .htaccess pour être sur :

    AddDefaultCharset UTF-8

    4) Mes fichiers sont enregistrés en UTF-8

    Résultat :

    En enregistrant des données via des formulaires sur mon site, tout semble ok, mes données s'affichent correctement sur le site.

    Chose étrange je n'ai même pas besoin d'ajouter ceci (pourquoi?) :

    Code:
    mysqli_set_charset($connect, "utf8");
    Si j'ajoute cette fonction juste après ma connexion, les caractères accentués s'affichent avec les é


    Par contre, forcément il faut toujours que ça cloche à un endroit, lorsque je regarde sur Phpmyadmin j'ai les é sur les caractères accentués. Pourtant lorsque je regarde le code source de la page HTML de phpmyadmin j'ai bien ceci :

    Code:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    PHPmyadmin devraient donc afficher ces données correctement si c'est bien de l'UTF-8 non? ou dois-je ne pas m'en préoccuper?

    Par contre si je saisis les données directement via phpmyadmin, les caractères s’affichent correctement sur phpmyadmin, mais s'affiche avec des � sur mon site. :roll:

    J'espère avoir été suffisamment clair :mrgreen:

    Une véritable plaie ces histoires de charset et d'interclassement.
     
  2. spout

    spout WRInaute accro

    Inscrit:
    14 Mai 2003
    Messages:
    8 663
    J'aime reçus:
    2
    Récapitulatif problèmes d'encodage:
    - Encodage des fichiers/scripts en UTF8 (sans BOM). :arrow: d'après ce que tu dis: OK
    - Headers HTTP ? Sont-ils bons ? :arrow: pas sur ?
    - HTML Meta charset ? Qui se défini: <meta charset="UTF-8"> en HTML5
    - Base de données MySQL: bon encodage ? SET NAMES UTF8 ?
     
  3. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Headers HTTP? C'est à dire?

    Ceci :

    Code:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    Et ceci dans le.htaccess n'est pas suffisant?

    Code:
    AddDefaultCharset UTF-8
    Que faut-il tester et faire pour voir et être certain que tout est ok au niveau du header HTTP (en local)?


    Et est-ce que mettre ceci :

    Code:
    <meta charset="UTF-8">
    change réellement quelque chose par rapport à ceci :

    Code:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    Comment vérifier que la BDD a le bon encodage? Quand je regarde ma base sur phpmyadmin je voix bien interclassement : utf8_general_ci

    Mais y a t-il une commande ou une requête que je pourrais taper dans phpmyadmin pour vérifier que mon encodage etc. est ok?

    Quelle est la différence entre encodage et interclassement? :?

    Ensuite est-il obligatoire d'utiliser set name UTF8 juste après la connexion dans son script PHP?
    J'avais lu que si normalement tout était bien configuré il n'y a aucune raison d'utiliser set name ( mysqli_set_charset($connect, "utf8"); )

    Dans mon cas dès que je fais un set name UTF 8 je me retrouve avec ces caractères é sur le site

    Je suis complètement pommé :(
     
  4. spout

    spout WRInaute accro

    Inscrit:
    14 Mai 2003
    Messages:
    8 663
    J'aime reçus:
    2
  5. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    j'utilise ce doctype :

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    Pour l'entête si j'ai ceci c'est ok?

    Code:
    HTTP/1.1 200 OK
    Set-Cookie: 90planBAK=R698937404; path=/; expires=Sat, 05-Oct-2013 09:46:11 GMT
    Date: Sat, 05 Oct 2013 08:46:12 GMT
    Content-Type: text/html; charset=UTF-8
    Connection: keep-alive
    Set-Cookie: 90plan=R3040346869; path=/; expires=Sat, 05-Oct-2013 09:46:58 GMT
    Server: Apache
    X-Powered-By: PHP/5.2.17
    Vary: Accept-Encoding
    PS : si un modérateur passe par la, pourrait-il déplacer le sujet dans la section développement (me suis trompé) :oops:
     
  6. spout

    spout WRInaute accro

    Inscrit:
    14 Mai 2003
    Messages:
    8 663
    J'aime reçus:
    2
    Donc d'après ton doctype, c'est bien : <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> que tu dois mettre.
    Tes headers HTTP sont bons.
     
  7. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    OK merci.

    Si j'analyse tout, mon encodage utf8 semble être ok mais c'est phpmyadmin qui affiche mal mon contenu. Une raison à cela?

    Et question importante. Quand on utilise de l'UTF8 est-il obligatoire d'utiliser cette fonction juste après la connexion?
    Code:
    mysqli_set_charset($connect, "utf8");
    (c'est la même chose que SET NAME UTF8)

    y a t-il une fonction pour tester que dans notre base les données sont bien enregistrées en UTF-8?
     
  8. spout

    spout WRInaute accro

    Inscrit:
    14 Mai 2003
    Messages:
    8 663
    J'aime reçus:
    2
  9. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    j'ai essayé d'abord de récuperer une version plus récente de phpmyadmin.

    j'ai constaté le même soucis.

    j'ai créé un petit script et une base de test, j'avais le même soucis, mais la en ajoutant mysqli_set_charset($connect, "utf8"); (ce qui équivaut au SET NAME UTF8) tout semble ok.

    ca s'affiche correctement sur le site, mais également sur phpmyadmin. Pour être certain que j'ai bien de l'UTF8 j'ai enregistré du texte en arabe et en russe. et il s'affiche correctement.

    Si mes données enregistrés ou si ma base était mal configuré je ne pourrais pas voir le texte en arabe ou en russe, exact?
     
  10. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    par contre si j'enlève le SET NAME UTF8, les caractères arabe etc. deviennent : ???????

    et les caractères accentués il me met ça : �

    Est-ce normal, qu'est-ce que ça signifie? :?

    J'aimerais vraiment comprendre quand et pourquoi mettre SET NAME UTF8. je voudrais vraiment êtrte certains que mon texte est bien inséré en UTF-8 dans la base :/
     
  11. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Personne ne pourrait m'expliquer le SET NAME UTF8?

    Pourquoi (en tout cas en local, pas testé sur mon hébergement) suis je obligé d'utiliser SET NAME UTF8 juste après ma connection à la BDD?

    Plus précisément je suis obligé de mettre la ligne de code suivante :

    Code:
    mysqli_set_charset($connect, "utf8");
    Est-ce dû à un problème de configuration quelque part? Comment être certain que mes données sont bien enregistrées en UTF-8 dans la base?
     
  12. rick38

    rick38 WRInaute impliqué

    Inscrit:
    23 Février 2013
    Messages:
    536
    J'aime reçus:
    0
    Parce qu'il faut dire à MySQL que tu lui envoies des requêtes en UTF-8, il ne peut pas deviner tout seul en quel encodage de ton côté tu lui envoies tes caractères, c'est comme ça, ça a toujours été comme ça, consulte la doc MySQL pour plus d'infos...
    Mettre dans la base de stocker en UTF-8 est une chose, lui dire d'interprêter la requête qu'il reçoit en tel ou tel encodage en est une autre (par défaut, Latin-1).

    Concernant le header, avant l'envoi du html, tu peux ajouter ceci pour être bien sûr que le navigateur comprenne que c'est uf-8 :

    header('Content-type: text/html; charset=utf-8');
     
  13. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Merci Rick.

    Si je comprend bien SET NAME UTF-8 s'utilise uniquement lorsque le serveur mysql n'est pas en UTF-8 par défaut chez notre hébergeur ou en local c'est bien ça?
    Donc on peut très bien avoir tout configuré correctement au niveau de notre base, tables, champs et header et avoir quand même besoin d'utiliser SET NAME UTF-8, exact? ai-je bien résumé ? :mrgreen:

    Donc si chez mon hébergeur je constate que je n'ai pas besoin de l'utiliser cela voudra dire que le serveur Mysql est configuré en UTF-8?

    Complexe ces histoires d'encodage :/
     
  14. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    J'en ai plein le c*l de ces histoires d'encodage.

    Comment se fait-il que lorsque je fais ceci :

    Code:
    echo mb_internal_encoding();
    ca m'indique ISO-8859-1

    C'est à quel niveau qu'il y a encore un soucis, qu'est-ce qui est encore en iso?

    J'ai mis mon header, ma base, mes tables, mes champs, mes fichiers en UTF8 et j'utilise SET NAME UTF-8 juste après ma connection à ma base, et pourtant il y a toujours un élément qui est en iso mais où?

    Y a pas à dire c'est un gros merdier ces histoires d'encodage
     
  15. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Faut-il vraiment passer toutes les fonctions str.. sous cette forme :

    mb_substr(blablabla, "UTF-8")
    mbstrtolower(blablabla,, "UTF-8")
    ...

    et

    htmlspecialchars(blablabla, ENT_COMPACT, "UTF-8");

    ou je me prend la tête pour rien?

    dans certains cas ça semble fonctionner sans avoir besoin de faire ça, j'y comprend plus rien. Suis je le seul à être autant à l'ouest avec l'encodage et à trouver ça extrêmement laborieux?

    je voudrais un maximum me préparer pour l'arrivé de php6 lorsque l'UTF-8 sera devenu la norme :/
     
  16. Blount

    Blount WRInaute impliqué

    Inscrit:
    18 Novembre 2010
    Messages:
    726
    J'aime reçus:
    0
    Bah, en lisant la doc de mb_internal_encoding, tu aurai vu qu'il suffit de faire : mb_internal_encoding("UTF-8"); pour définir l'utf-8 par défaut pour les fonction mb_*.
     
  17. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Je l'avais lu et je le sais ce n'était pas tout a fait la question. :wink:
    J'ai dû mal m'exprimer.

    C'est à quel niveau que c'est encore en iso? c'est le serveur PHP?
    Si c'est le cas et que par conséquent le serveur PHP est en iso faut-il obligatoirement que je fasse ceci : mb_internal_encoding("UTF-8");

    Que je fasse mb_internal_encoding("UTF-8"); ou non ça à l'air de rien changer au niveau de mon site, tout semble tourner exactement pareil.

    Mais dans les 2 cas je galère un peu. Dans certaines parties de mon code ça fonctionne très bien sans les mb_* et d'autres fois je suis obligé de me servir des mb_*

    J'en perd mon latin. Lorsqu'on est en utf-8 faut-il remplacer toutes nos fonctions de traitements de chaines par les fonctions mb_*? ou vous aussi vous avez parfois des subtsr, strtolower etc. sans passer par leur version mb_*?

    Avec tous ce qu'il y a savoir et à modifier pour faire de l'UTF-8 j'ai vraiment l'impression que je vais oublier des choses importantes pour un codage propre :?
     
  18. Blount

    Blount WRInaute impliqué

    Inscrit:
    18 Novembre 2010
    Messages:
    726
    J'aime reçus:
    0
    Oui, il est préférable de toujours utiliser les fonctions mb_* pour l'UTF8.

    Il suffit de faire quelques tests pour s'en apercevoir :
    PHP:
    <span class="syntaxdefault"><br /></span><span class="syntaxkeyword"><?</span><span class="syntaxdefault">php<br /><br />mb_internal_encoding</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"UTF-8"</span><span class="syntaxkeyword">);<br /><br /></span><span class="syntaxdefault">$test </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"caractère É"</span><span class="syntaxkeyword">;<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"Mettre en minuscule: strtolower\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">strtolower</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nMettre en minuscule: mb_strtolower\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">mb_strtolower</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nMettre en majuscule: strtoupper\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">strtoupper</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nMettre en majuscule: mb_strtoupper\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">mb_strtoupper</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nCompter le nombre de caractères: strlen\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">strlen</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nCompter le nombre de caractères: mb_strlen\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">mb_strlen</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nTrouver la position du 'É': strpos\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">strpos</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"É"</span><span class="syntaxkeyword">));<br /><br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">"\nTrouver la position du 'É': mb_strpos\n"</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">mb_strpos</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"É"</span><span class="syntaxkeyword">));<br /></span><span class="syntaxdefault"> </span>
    La sortie :
    Code:
    Mettre en minuscule: strtolower
    string(13) "caractère É"
    
    Mettre en minuscule: mb_strtolower
    string(13) "caractère é"
    
    Mettre en majuscule: strtoupper
    string(13) "CARACTèRE É"
    
    Mettre en majuscule: mb_strtoupper
    string(13) "CARACTÈRE É"
    
    Compter le nombre de caractères: strlen
    int(13)
    
    Compter le nombre de caractères: mb_strlen
    int(11)
    
    Trouver la position du 'É': strpos
    int(11)
    
    Trouver la position du 'É': mb_strpos
    int(10)
    
    
    Je ne vais pas faire toute la liste ;)

    Il y a déjà quelques années, j'ai écris un article sur cette problématique des accents. Cela fait déjà plus de 3 ans, et il est toujours d'actualité.
    http://programmation-web.net/2010/11/comment-resoudre-les-problemes-daccents/
    Tu en connais déjà les gros morceaux, mais il t'apportera peut-être des trucs.

    J'ai aussi un autre article qui explique comment enlever les accents d'une chaîne de caractères. Ça permet aussi de convertir facilement des chaînes d'un jeu à l'autre.
     
  19. spout

    spout WRInaute accro

    Inscrit:
    14 Mai 2003
    Messages:
    8 663
    J'aime reçus:
    2
  20. noren

    noren WRInaute accro

    Inscrit:
    8 Avril 2011
    Messages:
    2 918
    J'aime reçus:
    0
    Merci bcp pour ces infos et liens je vais étudier tout ça :wink:

    Dure dure de s'y remettre après plus de 6-7 ans d'hibernation :oops:

    j'ai constaté qu'il y avait également d'autres problèmes, certaines fonctions ne sont pas adaptées pour l'UTF8 : substr_replace. Cette fonction n'a pas son équivalent en mb_*, c'est également ce genre de chose qui doivent poser quelques problèmes sur mon appli.

    J'ai trouvé ceci pour remplacer :

    Code:
    function my_mb_substr_replace($original, $replacement, $position, $length)
    {
     $startString = mb_substr($original, 0, $position, ENCODAGE);
     $endString = mb_substr($original, $position + $length, mb_strlen($original, ENCODAGE), ENCODAGE);
     
     $out = $startString . $replacement . $endString;
     
     return $out;
    }
    Par contre j'ai l'impression que str_replace et preg_replace ne posent pas de problèmes, il n'y a d'ailleurs pas de version mb_*
     
  21. MisterArabic

    MisterArabic Nouveau WRInaute

    Inscrit:
    19 Février 2014
    Messages:
    1
    J'aime reçus:
    0
    Extraire et afficher correctement en arabe les données d'une table PHP/MySQL dans une page de résultat PHP sous Dreamweaver 8®

    SƲMARAßƲS.com

    Objectif du cours :

    - obtenir l'affichage correct en arabe des données extraites d'une table.

    MODE OPÉRATOIRE :

    PREMIÈRE PARTIE :

    Afficher les caractères arabes dans une table MySQL avec Wampserver® :

    1. Créer une Table.

    2. Dans le champ Interclassement, sélectionner "utf8_bin" comme langue d'affichage.

    3. Enregistrer en cliquant sur Sauvegarder.

    DEUXIÈME PARTIE :

    1. Ouvrir la page de résultats et repérer la ligne suivante :
    mysql_select_db($database_MaBase, $MaTable);

    2. Copier/coller les deux lignes suivantes immédiatement en dessous :
    mysql_query("SET NAMES cp1256");
    mysql_query("set characer set cp1256");

    Cela donne :

    mysql_select_db($database_MaBase, $MaTable);

    mysql_query("SET NAMES cp1256");
    mysql_query("set characer set cp1256");

    3. Attribuer à la page de Résultats la police de caractère "Windows-1256" comme cela :
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1256" />

    4. Enregistrer.

    Source : sumarabus.com partie "Tutoriels arabes" (Tutoriels sur les particularités de la langue arabe pour la création de pages webs).

    Autres Tutoriels disponibles : "Créer un clavier arabe virtuel", "Afficher la date en arabe", etc...
    Ma3a assalama,
    Mister Arabic.