UTF-8 - Ein Buch mit 7 Siegeln?
eigentlich nicht, sobald man beginnt die Logik dahinter zu verstehen!
Wie versteht man diese Logik am besten? Einfach, indem man sie erklärt bekommt! Was genau ich jetzt versuche zu tun.
Es reicht zurück bis zu den ersten Computern. Im Anfang herrschte das Chaos (nein, jetzt kommt nicht die Genesis!) und jeder Hersteller kochte seine eigene Suppe. Einfacher Datentausch (per Lochkarte, Lochstreifen oder Magnetband/-draht) war fast unmöglich. Aber Menschen und Unordnung? Geht gar nicht!
So wurde der American Standard Code for Information Interchange eingeführt. Das war bereits am 17. Juni 1963 !!
Der ASCII-Standard basiert auf einem 7-Bit Code und definiert 128 Zeichen, bestehend aus 33 nicht druckbaren sowie 95 druckbaren Zeichen.
Die druckbaren Zeichen umfassen das lateinische Alphabet in Groß- und Kleinschreibung, die zehn arabischen Ziffern sowie einige Interpunktionszeichen (Satzzeichen, Wortzeichen) und andere Sonderzeichen. Der Zeichenvorrat entspricht weitgehend dem einer Tastatur oder Schreibmaschine für die englische Sprache. Die nicht druckbaren Steuerzeichen enthalten Ausgabezeichen wie Zeilenvorschub oder Tabulatorzeichen, Protokollzeichen wie Übertragungsende oder Bestätigung und Trennzeichen wie Datensatztrennzeichen. Die genauen Spezifikationen dazu sind hier zu finden: American Standard Code for Information Interchange
Fast alle später definierten Standards basieren noch heute, 60 Jahre später, auf diesem 7-Bit ASCII-Code. E-Mails werden z.B. grundsätzlich als 7-Bit Code übertragen.
Mit der fortschreitenden Internationalisierung genügten die verfügbaren 95 Zeichen nicht mehr. Auf Grund dessen wurde der Code um 1 Bit auf 8-Bit erweitert. Das bedeutete, dass 128 zusätzliche Zeichen verfügbar waren. Um jetzt den Unterschiedlichsten Sprachen und Schriften gerecht zu werden, wurde für jede Sprache/Schrift eine eigene Codepage und/oder ISO 8859 entworfen. All diese waren in den ersten 128 Zeichen identisch und in den oberen 128 Zeichen (128-255) wurden die Sprachspezifischen Zeichen abgelegt. Recht schnell genügten auch diese zusätzlichen Zeichen nicht mehr aus. Zumal sich auch das Problem ergab, dass keine 2 Schriften gleichzeitig eingesetzt werden konnten.
All diese Probleme führten dazu, dass der UNICODE Zeichensatz, der je Zeichen aus mehreren Bytes (n*8-Bit) bestehen kann, entwickelt wurde. Codiert wurden diese Zeichen dann u.A. nach dem UTF-8 Schema, welches dynamisch je Zeichen aus einem, zwei, drei oder gar 4 Bytes bestehen kann. Auch bei UTF-8 sind die ersten 128 Zeichen weiterhin identisch zum ursprünglichen ASCII-Code. Zusätzlich gibt es noch eine ganze Reihe weiterer UTF Codierungen: UTF-7, UTF-16, UTF-32LE, UTF-32BE, UTF-EBCDIC, usw., die aber natürlich alle Unicode Zeichen darstellen.
Hier stehen jetzt viele Editoren/Textverarbeitungen „auf dem Schlauch“. Irgendwoher müssen sie ja erfahren, in welcher Codierung ein geladener Text eigentlich vorliegt! Der einfache Benutzer von MS-Word etc. ist der Textverarbeitung dabei in der Regel keine große Hilfe.
Ggenau hier kommt jetzt aber die BOM, die Byte-Order-Mark ins Spiel. Diese BOM ist bei allen UTF-Codierungen nichts anderes als das Unicodezeichen U+FEFF, das in der jeweiligen Codierungsart codiert wird. Bei UTF-8 ist das die Bytefolge 0xEF + 0xBB + 0xBF die bei falscher Decodierung oft als die sinnvolle Zeichenfolge  ausgegeben wird.
Durch die BOM braucht ein Editor einfach nur die ersten Bytes einer Datei lesen und durch simplen Vergleich mit seiner internen Tabelle erkennt er sofort die Codierungsart der Datei.
Alles in allem: Eine saubere, einfache Sache. Wenn, ja wenn da nicht die ganzen Programmierer mit ihren Werkzeugen wären!!!
Denn diese (also die Werkzeuge) stören sich gewaltig an den 'überflüssigen' Zeichen vor den eigentlichen Daten. Nehmen wir der Einfachheit halber PHP in Verbindung mit einem Webserver.
Die grundlegende Tätigkeit eines Webservers ist es, aufgerufene Dateien auf der Festplatte zu finden, einzulesen und 1:1 direkt wieder auszugeben. Bestes Beispiel sind hierfür die *.html oder *.txt Dateien. Enthält jedoch z.B. eine *html Datei eine BOM, so wird der Browser dieses als erstes, noch vor dem <!doctype html>
erhalten und auch anzeigen. Auf dem Browser wird das im Quelltext so aussehen: <!doctype html>
. Nicht so schön?? Sag ich auch. Zumal die Zeichenausgabe vor dem Doctype manchen Browser in den Quirks-Modus zwingt, was wiederum Boxmodell und CSS in's Schleudern bringen kann.
In Verbindung mit PHP wird es nicht nur eine optische, sondern bereits eine Funktionsstörung erzeugen. Der Server erkennt anhand der Endung (z.B. *.php), dass er die Datei anders behandeln muss. Er liest die Datei ein und gibt sie direkt zum Browser aus… solange, bis er auf ein <?php
Tag trifft, was bei reinen *.php Dateien lt. Coding Standards in Zeile1/Spalte1 der Fall sein sollte. Von hier ab bis zum ersten ?>
Tag, oder falls keines kommt bis zum Dateiende, schickt er die Daten jetzt erst mal zum PHP-Interpreter, der diese als Script behandelt, ausführt und das Ergebnis an den Server zurück gibt, der es zum Browser weiterleitet.
Hat die Datei eine BOM, dann setzt sich die vor das <?php und erzeugt dadurch wiederum eine unerwünschte Ausgabe der drei Zeichen . Optisch nicht schön, technisch eine Katastrophe, denn durch die Ausgabe kann PHP keine Header mehr senden. Also nix mehr los mit dem allseits beliebten header(location….) oder Cookie setzen… oder.. oder
Weshalb gibt es bei mySQL außer UTF8 auch noch die UTF8mb4 Kodierung?
Also grundsätzlich: das offizielle UTF-8 (wie es auch in PHP verwendet wird) kann Zeichen mit 1-4 Byte großer Codierung benutzen.
mySQL hat damals, als UTF-8 noch nicht so verbreitet war, dieses implementiert. Um Platz zu sparen wurde jedoch nur eine 1-3 Byte große Codierung benutzt.
Nach ein paar Jahren erkannte man, dass man doch den vollen Umfang von UTF-8 benötigt. Eine Anpassung auf 4 Byte war jedoch aus verschiedenen Gründen nicht möglich. Deshalb wurde ein zweites UTF-8 Format, nämlich das UTF8mb4 definiert, das in der Lage ist den vollen UTF-8 Umfang mit 1-4 Bytes aufzunehmen.
Für uns ist es nur wichtig zu wissen, dass das UTF8 von PHP absolut kompatibel ist zu dem UTF8mb4 von mySQL.