[Entwicklung] [Entwicklung] Die UTF8-Verschw�rung - Druckversion +- PHP Rocks (https://www.php-rocks.de) +-- Forum: Knowledge Base (https://www.php-rocks.de/https://www.php-rocks.de/forum/18-knowledge-base.html) +--- Forum: Tutorials (https://www.php-rocks.de/https://www.php-rocks.de/forum/20-tutorials.html) +--- Thema: [Entwicklung] [Entwicklung] Die UTF8-Verschw�rung (/https://www.php-rocks.de/thema/98--entwicklung-die-utf8-verschw-rung.html) |
[Entwicklung] Die UTF8-Verschw�rung - Arne Drews - 15.04.2016 Die UTF8-Verschw�rung Man mag es kaum glauben, aber auch in der heutigen Zeit werden Projekte online gestellt, die ein Problem mit Sonderzeichen haben. In diesem kleinen Tutorial möchte ich euch das Ganze etwas näher bringen, in der Hoffnung, dass die Mystik dessen etwas verschwindet. Was bedeutet "Sonderzeichen"? Um den Begriff Sonderzeichen im Zusammenhang mit diesem Tutorial zu definieren, sollte man wissen, dass wir von sogenannten Zeichenkodierungen und Kodierungstabellen sprechen. Alle Zeichen, die wir auf dem Bildschirm darstellen können, entstammen aus einer Zeichenkodierungen-Tabelle. Wenn wir nun versuchen ein Zeichen auszugeben, das sich in der verwendeten Tabelle nicht befindet, kommt es zu unerwünschten Ausgaben, die wir sicher alle schon mal gesehen haben. Als Beispiel soll dieses kleine HTML mal herhalten: Code: <html> Ausgabe: Hier steht ein ganz gew�hnlicher Satz mit lauter bekannten Zeichen Wo liegt mein Fehler? Hier liegt ein Problem mit der Zeichenkodierung vor. Zugegeben, hier wäre es mit ein wenig Erfahrung leicht, die Kodierung an der richtigen Stelle zu setzen, um alles korrekt anzeigen zu lassen. Aber wir wollen heute mal alles richtig machen und schauen uns dazu mal kurz im Überblick an, an welchen Stellen wir auf eine korrekte Kodierung achten und diese konsequent auch einsetzen sollten:
Keine Angst, was das im einzelnen bedeutet, gehen wir jetzt mal Schritt für Schritt durch... Speicherung von Dateien Eure Dateien sollten immer als UTF-8 ohne BOM gespeichert werden. Viele gute Editoren oder IDE's bieten die Möglichkeit, die Kodierung beim Speichern einer Dateien einzustellen. Beispielhaft wäre das im SublimeText 3 über den Menüpunkt File -> Save with Encoding -> UTF-8 erledigt oder ihr geht auf File -> Reopen with Encoding -> UTF-8 und speichert die Datei dann wieder. Aber auch andere Editoren, wie bspw. Notepad++ haben diese Möglichkeiten. HinweisDas BOM ( ByteOrderMark ) ist eine Kennung für die Unicode-Kodierung, die den Datenstrom einleitet und im Falle von UTF8 aus der BytesequenzEF BB BF besteht.Das wird in Browsern häufig als  interpretiert und ausgegeben ( im Quelltext des Browsers erkennbar ).Das führt häufig zu bekannten Fehlern, wie Cannot add header information. Daher sollte man immer darauf achten, dass Dateien immer ohne BOM gespeichert werden! HTTP Header Im HTTP-Header werden Informationen über das Dokument, sowie HTTP-Cookies und Kennungen für den HTTP-Server, User-Agent und MIME-Typ übertragen. Hier muß für unseren Zweck die entsprechende Kodierung bestimmt werden. Das geht bspw. über folgende PHP-Anweisung: PHP-Code: header ( 'Content-Type: text/html; Charset=utf-8' ); HinweisBei der Verwendung derheader() -Anweisung ist darauf zu achten, dass diese am Anfang des Root-Scriptes vor sämtlichen Ausgaben erfolgt, da ihr sonst schnell wieder den bereits erwähnten Fehler Cannot add header information bekommt.<meta>-Tag Um auch dem Browser mitzuteilen, welche Codierung wir in dem Dokument verwenden, müssen wir dies per <meta> -Tag entsprechend dem verwendeten <!DOCTYPE mitteilen:Für Dokumente mit HTML4.x-Doctype: Code: <meta http-equiv="content-type" content="text/html; charset=utf-8" /> Code: <meta charset="utf-8"> <meta> -Tag wird im <head> des Dokuments, am besten direkt nach dem <title> -Tag angegeben.TippSolltet ihr Formulare verwenden, setzt am besten auch darin gleich die korrekte Kodierung für die Datenübertragung:Code: <form name="form" method="post" accept-charset="utf-8"> Datenbankverbindung Verwendet ihr in eurem Projekt eine Datenbank, ist natürlich auch darauf zu achten, dass die Daten über eine einheitliche Kodierung ausgetauscht werden. Für die Verbindung mit der Datenbank ( hier beispielhaft MySQL ) können wir dies wie folgt angeben: PDO: PHP-Code: $oDB = new PDO( 'mysql:host=localhost;dbname=exampledb;charset=utf8', $username, $password ); PHP-Code: $oDB = new MySQLi ( 'localhost', $username, $password, 'exampledb' ); HinweisIn Bezug auf PDO sei erwähnt, dass der Parameter charset im DSN ( Data Source Name ) in PHP-Versionen vor 5.3.6 ignoriert wurde. Solltet ihr tatsächlich noch eine dieser Versionen haben, müsst ihr die Kodierung ähnlich folgender Weise setzen:PHP-Code: $options = array( MYSQL_ATTR_INI_COMMAND => 'set names utf8' ); Kollation der Tabellen, Spalten und der Datenbank selbst Wenn wir dafür sorgen, dass die Verbindung zur Datenbank sauber über UTF-8 abgewickelt wird, müssen wir natürlich auch die Datenhaltung sinnvoller Weise darauf auslegen. Hierzu gibt es in Administrations-Tools, wie etwa phpMyAdmin ( MySQL ), pgAdmin ( pgSQL ), u.w. eine Einstellung, die sich Kollation ( Collation ) nennt. Hier kann sowohl auf Datenbank-, Tabellen- und Spalten-Ebene festgelegt werden, mit welcher Kodierung gearbeitet werden soll. Die gängigsten Kollationen in dem Bereich Unicode sind utf8_unicode_ci und utf8_general_ci . Nennenswerter Unterschied ist die genauere Sortierung bei utf8_unicode_ci , während utf8_general_ci etwas mehr Performance nachgesagt wird. Weitere nennenswerte Unterschiede sind mir von den verschiedenen utf8_ -Kodierungen nicht bekannt. Ein Spezialfall bildet allerdings utf8_bin , das die Vergleiche im Binär-Format durchführt.HinweisSollte euer verwendetes DBMS utf8mb4 unterstützen, wäre das die noch die bessere Wahl. Damit stehen euch bis zu 4 Bytes pro Character zur Verfügung, womit ein zusätzlicher Umfang an Character dargestellt werden kann. MySQL unterstützt utf8mb4 ab Version 5.3.3Danke an @mermshaus für die Info: http://www.php-rocks.de/thema/143;777-re-utf-8-verschwoerung-ergaenzung.html#pid777 Sonderfälle Aus diesem Tutorial solltet ihr mitnehmen, dass ihr immer mit der richtigen Kodierung arbeitet und zwar an jeder Stelle, an der ihr Einfluss darauf habt! Es gibt allerdings Situationen, in denen man vielleicht keinen Einfluss auf die Daten-Kollation hat. Bspw. bei einer Datenbank-Migration aus einer alten Datenbank in eine neue. Die alte Datenbank hält die Daten nicht in UTF-8 vor und ihr müsst diese zu UTF-8 in die neue übertragen. Hier wäre bspw. die PHP-Funktion utf8_encode() oder mb_convert_encoding() zu verwenden. HinweisVielleicht ist dem einen oder anderen bereits aufgefallen, dass auf Datenbank- und Datenbankverbindungs-Ebene grundsätzlichutf8 und in allen anderen Kontexten utf-8 verwendet wird. Wer sich daran hält, spart sich manche Fehlersuche... |