it-swarm.com.de

Probleme mit UTF-8-Zeichen; Was ich sehe, ist nicht das, was ich gespeichert habe

Ich habe versucht, UTF-8 zu verwenden und bin auf Probleme gestoßen.

Ich habe so viele Dinge versucht; Hier sind die Ergebnisse, die ich erhalten habe:

  • ???? statt asiatischer Zeichen. Sogar für europäischen Text habe ich Se?or zum Señor.
  • Seltsamer Kauderwelsch (Mojibake?) Wie Señor oder 新浪新闻 zum 新浪新闻.
  • Schwarze Diamanten wie Se�or.
  • Schließlich geriet ich in eine Situation, in der die Daten verloren gingen oder zumindest abgeschnitten wurden: Se für Señor.
  • Selbst wenn ich Text zu schauen richtig erhalten habe, hat es sortieren nicht richtig funktioniert.

Was mache ich falsch? Wie kann ich den Code reparieren? Kann ich die Daten wiederherstellen, wenn ja, wie?

59
Rick James

Dieses Problem plagt die Teilnehmer dieser Website und viele andere.

Sie haben die fünf Hauptfälle von CHARACTER SET - Problemen aufgelistet.

Best Practice

In Zukunft ist es am besten, CHARACTER SET utf8mb4 Und COLLATION utf8mb4_unicode_520_ci Zu verwenden. (Es befindet sich eine neuere Version der Unicode-Kollatierung in der Pipeline.)

utf8mb4 Ist eine Obermenge von utf8, Da es 4-Byte-utf8-Codes verarbeitet, die von Emoji und einigen Chinesen benötigt werden.

Außerhalb von MySQL bezieht sich "UTF-8" auf alle Größenkodierungen, daher praktisch gleich wie MySQLs utf8mb4, Nicht utf8.

Ich werde versuchen, diese Schreibweisen und Großbuchstaben zu verwenden, um im Folgenden zwischen inside und outside MySQL zu unterscheiden.

Überblick darüber, was Sie sollten tun

  • Stellen Sie Ihren Editor usw. auf UTF-8 ein.
  • HTML-Formulare sollten wie folgt beginnen: <form accept-charset="UTF-8">.
  • Lassen Sie Ihre Bytes als UTF-8 codieren.
  • Richten Sie UTF-8 als die im Client verwendete Codierung ein.
  • Lassen Sie die Spalte/Tabelle mit CHARACTER SET utf8mb4 Deklarieren (mit SHOW CREATE TABLE Prüfen).
  • <meta charset=UTF-8> Am Anfang von HTML

TF-8 bis zum Ende

Weitere Details für Computersprachen (und die folgenden Abschnitte)

Testen Sie die Daten

Das Anzeigen der Daten mit einem Tool oder mit SELECT kann nicht als vertrauenswürdig eingestuft werden. Zu viele solcher Clients, insbesondere Browser, versuchen, falsche Codierungen zu kompensieren, und zeigen Ihnen korrekten Text an, selbst wenn die Datenbank entstellt ist. Suchen Sie sich also eine Tabelle und eine Spalte aus, die nicht englischen Text enthält, und tun Sie dies

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

Das HEX für korrekt gespeichertes UTF-8 wird sein

  • Für ein Leerzeichen (in einer beliebigen Sprache): 20
  • Für Englisch: 4x, 5x, 6x Oder 7x
  • In den meisten westeuropäischen Ländern sollten Buchstaben mit Akzent Cxyy sein.
  • Kyrillisch, Hebräisch und Persisch/Arabisch: Dxyy
  • Großteil Asiens: Exyyzz
  • Emoji und einige Chinesen: F0yyzzww
  • Weitere Details

Spezifische Ursachen und Lösungen für die aufgetretenen Probleme

Abgeschnittener Text (Se für Señor):

  • Die zu speichernden Bytes werden nicht als utf8mb4 codiert. Repariere das.
  • Überprüfen Sie außerdem, ob die Verbindung während des Lesens UTF-8 ist.

Schwarze Diamanten mit Fragezeichen (Se�or Für Señor); Einer dieser Fälle liegt vor:

Fall 1 (ursprüngliche Bytes waren nicht UTF-8):

  • Die zu speichernden Bytes werden nicht als utf8 codiert. Repariere das.
  • Die Verbindung (oder SET NAMES) Für das INSERT und das SELECT war nicht utf8/utf8mb4. Repariere das.
  • Überprüfen Sie außerdem, ob die Spalte in der Datenbank CHARACTER SET utf8 (Oder utf8mb4) lautet.

Fall 2 (ursprüngliche Bytes waren UTF-8):

  • Die Verbindung (oder SET NAMES) Für das SELECT war nicht utf8/utf8mb4. Repariere das.
  • Überprüfen Sie außerdem, ob die Spalte in der Datenbank CHARACTER SET utf8 (Oder utf8mb4) lautet.

Schwarze Rauten treten nur auf, wenn der Browser auf <meta charset=UTF-8> Eingestellt ist.

Fragezeichen (reguläre, keine schwarzen Diamanten) (Se?or Für Señor):

  • Die zu speichernden Bytes werden nicht als utf8/utf8mb4 codiert. Repariere das.
  • Die Spalte in der Datenbank ist nicht CHARACTER SET utf8 (Oder utf8mb4). Repariere das. (Verwenden Sie SHOW CREATE TABLE.)
  • Überprüfen Sie außerdem, ob die Verbindung während des Lesens UTF-8 ist.

Mojibake (Señor Für Señor): (Diese Diskussion gilt auch für Double Encoding , was nicht unbedingt sichtbar ist.)

  • Die zu speichernden Bytes müssen UTF-8-codiert sein. Repariere das.
  • Die Verbindung, wenn INSERTing und SELECTing Text utf8 oder utf8mb4 angeben müssen. Repariere das.
  • Die Spalte muss mit CHARACTER SET utf8 (Oder utf8mb4) deklariert werden. Repariere das.
  • HTML sollte mit <meta charset=UTF-8> Beginnen.

Wenn die Daten korrekt aussehen, aber nicht richtig sortiert werden, haben Sie entweder die falsche Kollatierung ausgewählt oder es gibt keine Kollatierung, die Ihren Anforderungen entspricht, oder Sie haben Doppelkodierung .

Doppelkodierung kann mit dem oben beschriebenen SELECT .. HEX .. Bestätigt werden.

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

Das heißt, das Hex ist ungefähr doppelt so lang wie es sein sollte. Dies wird verursacht, indem von latin1 (oder was auch immer) nach utf8 konvertiert wird, diese Bytes dann so behandelt werden, als wären sie latin1, und die Konvertierung wiederholt wird. Das Sortieren (und Vergleichen) funktioniert nicht richtig, da beispielsweise so sortiert wird, als wäre der String Señor.

Fixierung der Daten, soweit möglich

Bei Trunkation und Question Marks gehen die Daten verloren.

Für Mojibake / Double Encoding , ...

Für schwarze Diamanten , ...

(Ich werde dies in einer anderen Frage/Antwort fortsetzen müssen.)

97
Rick James

Ich hatte ähnliche Probleme mit zwei meiner Projekte nach einer Servermigration. Nachdem ich viele Lösungen gesucht und ausprobiert hatte, stieß ich auf diese:

mysqli_set_charset($con,"utf8");

Nach dem Hinzufügen dieser Zeile zu meiner Konfigurationsdatei funktioniert alles einwandfrei!

Ich fand diese Lösung für mysqli https://www.w3schools.com/PHP/func_mysqli_set_charset.asp , als ich suchte, eine Einfügung von der HTML-Abfrage zu lösen

viel Glück!

4
castro_pereira

Lustig, wie du deine eigene Frage beantwortest :)

  1. Setzen Sie Ihren Code IDE language auf UTF8

  2. Fügen Sie Ihrem Webseiten-Header hinzu, in dem Sie das Datenformular erfassen.

  3. Überprüfen Sie, ob Ihre MySQL-Tabellendefinition folgendermaßen aussieht:

    CREATE TABLE your_table (
      ...
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    
  4. Wenn Sie PDO verwenden, stellen Sie sicher

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

Wenn Sie bereits eine große Datenbank mit dem oben genannten Problem haben, können Sie versuchen, SIDU mit dem richtigen Zeichensatz zu exportieren und mit UTF8 wieder zu importieren. Viel Glück

2
SIDU