Problème avec les caractères UTF-8; ce que je vois n’est pas ce que j’ai stocké

J’ai essayé d’utiliser UTF-8 et j’ai rencontré des problèmes.

J’ai essayé tellement de choses; voici les résultats que j’ai obtenus:

  • ???? au lieu de caractères asiatiques. Même pour le texte européen, j’ai eu Se?or pour Señor .
  • Un charabia étrange (Mojibake?) Tel que Señor ou 新浪新闻 pour 新浪新闻 .
  • Les diamants noirs, tels que Se or.
  • Enfin, je me suis retrouvé dans une situation où les données étaient perdues ou du moins tronquées: Se pour Señor .
  • Même lorsque le texte a l’ air correct, il n’a pas été sortingé correctement.

Qu’est-ce que je fais mal? Comment puis-je corriger le code ? Puis-je récupérer les données , si oui, comment?

Ce problème affecte les participants de ce site et de nombreux autres.

Vous avez répertorié les cinq principaux cas de problèmes CHARACTER SET .

Meilleur entrainement

À l’avenir, il est préférable d’utiliser CHARACTER SET utf8mb4 et COLLATION utf8mb4_unicode_520_ci . (Il existe une version plus récente du classement Unicode dans le pipeline.)

utf8mb4 est un sur-ensemble de utf8 en ce sens qu’il gère les codes utf8 de 4 octets, nécessaires à Emoji et à certains chinois.

En dehors de MySQL, “UTF-8” fait référence à tous les encodages de taille, donc effectivement identiques à ceux de MySQL utf8mb4 , pas utf8 .

Je vais essayer d’utiliser ces orthographes et ces majuscules pour distinguer l’intérieur et l’extérieur de MySQL dans ce qui suit.

Aperçu de ce que vous devriez faire

  • Placez votre éditeur, etc. sur UTF-8.
  • Les formulaires HTML doivent commencer par

    .

  • Ayez vos octets encodés en UTF-8.
  • Établissez UTF-8 comme codage utilisé dans le client.
  • Avoir la colonne / table déclarée CHARACTER SET utf8mb4 (vérifier avec SHOW CREATE TABLE .)
  • au début de HTML

UTF-8 jusqu’au bout

Plus de détails sur les langages informatiques (et ses sections suivantes)

Tester les données

L’affichage des données avec un outil ou avec SELECT ne peut pas être fiable. Trop de tels clients, en particulier les navigateurs, essaient de compenser les encodages incorrects et vous montrent du texte correct même si la firebase database est endommagée. Alors, choisissez une table et une colonne contenant du texte non anglais et faites

 SELECT col, HEX(col) FROM tbl WHERE ... 

Le HEX pour UTF-8 correctement stocké sera

  • Pour un espace vide (dans n’importe quelle langue): 20
  • Pour l’anglais: 4x , 5x , 6x ou 7x
  • Pour la plupart des pays d’Europe occidentale, les lettres accentuées devraient être Cxyy
  • Cyrillique, hébreu et farsi / arabe: Dxyy
  • La plupart de l’Asie: Exyyzz
  • Emoji et quelques Chinois: F0yyzzww
  • Plus de détails

Causes spécifiques et corrections des problèmes rencontrés

Texte tronqué ( Se pour Señor ):

  • Les octets à stocker ne sont pas codés en utf8mb4. Répare ça.
  • Vérifiez également que la connexion lors de la lecture est UTF-8.

Diamants noirs avec des points d’interrogation ( Se or pour Señor ); l’un de ces cas existe:

Cas 1 (les octets d’origine n’étaient pas UTF-8):

  • Les octets à stocker ne sont pas encodés en utf8. Répare ça.
  • La connexion (ou SET NAMES ) pour l’ INSERT et le SELECT n’était pas utf8 / utf8mb4. Répare ça.
  • Vérifiez également que la colonne dans la firebase database est CHARACTER SET utf8 (ou utf8mb4).

Cas 2 (les octets d’origine étaient UTF-8):

  • La connexion (ou SET NAMES ) pour le SELECT n’était pas utf8 / utf8mb4. Répare ça.
  • Vérifiez également que la colonne dans la firebase database est CHARACTER SET utf8 (ou utf8mb4).

Les diamants noirs apparaissent uniquement lorsque le navigateur est défini sur .

Points d’interrogation (réguliers, pas de diamants noirs) ( Se?or pour Señor ):

  • Les octets à stocker ne sont pas codés en utf8 / utf8mb4. Répare ça.
  • La colonne de la firebase database n’est pas CHARACTER SET utf8 (ou utf8mb4). Répare ça. (Utilisez SHOW CREATE TABLE .)
  • Vérifiez également que la connexion lors de la lecture est UTF-8.

Mojibake ( Señor pour Señor ): (Cette discussion s’applique également à Double Encoding , qui n’est pas nécessairement visible.)

  • Les octets à stocker doivent être codés en UTF-8. Répare ça.
  • La connexion lorsque le texte INSERTing et SELECTing doit spécifier utf8 ou utf8mb4. Répare ça.
  • La colonne doit être déclarée CHARACTER SET utf8 (ou utf8mb4). Répare ça.
  • HTML devrait commencer par .

Si les données semblent correctes, mais ne sont pas sortingées correctement, vous avez choisi le mauvais classement ou il n’y a pas de classement adapté à vos besoins, ou vous avez Double Encoding .

Le codage double peut être confirmé en effectuant la commande SELECT .. HEX .. décrite ci-dessus.

 é should come back C3A9, but instead shows C383C2A9 The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD 

C’est-à-dire que l’hex est environ deux fois plus long que prévu. Cela est dû à la conversion de latin1 (ou autre) en utf8, puis en traitant ces octets comme s’ils étaient latin1 et en répétant la conversion. Le sorting (et la comparaison) ne fonctionne pas correctement car il s’agit, par exemple, de sortinger comme si la chaîne était Señor .

Fixer les données, si possible

Pour les points de troncature et les points d’ interrogation , les données sont perdues.

Pour Mojibake / Double Encoding , …

Pour les diamants noirs , …

(Je vais devoir continuer dans une autre question / réponse.)

C’est drôle comme vous répondez à votre propre question 🙂

  1. Définissez la langue de votre code IDE sur UTF8

  2. Ajoutez à votre en-tête de page Web où vous collectez le formulaire de données.

  3. Vérifiez que votre définition de table MySQL ressemble à ceci:

     CREATE TABLE your_table ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8 
  4. Si vous utilisez PDO, assurez-vous que

     $options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); $dbL = new PDO($pdo, $user, $pass, $options); 

Si vous avez déjà une grande firebase database avec le problème ci-dessus, vous pouvez essayer SIDU pour exporter avec le jeu de caractères correct et réimporter avec UTF8. Bonne chance

Selon la configuration du serveur, vous devez modifier l’encodage en conséquence. utf8 d’après ce que vous avez dit devrait fonctionner le mieux, mais si vous obtenez des caractères étranges, cela pourrait aider si vous changez la page Web Encode en Ansi. Cela m’a aidé lors de la configuration de PHP MYSQLI, cela pourrait vous aider à mieux comprendre https://superuser.com/questions/762473/ansi-to-utf-8-in-notepad