[HTML/PHP] UTF-8 vs. Sonderzeichen

Das ist so nicht korrekt. Wie erwähnt, läuft zumindest unter Debian Wheezy MySQL intern immer noch mit latin1. Debian kommt im Webhostingberech recht häufig zum Einsatz, Wheezy ist als aktuelle Version sicherlich auch noch am ehesten in Richtung UTF-8 umgestellt. Man muss also in der Standardkonfiguration weiterhin die Kodierung der Datenbanken/Tabellen/Spalten explizit angeben. Gut, möglicherweise ist man bei anderen Distributionen einen Schritt weiter, das habe ich nicht geprüft.

PHP selbst kennt bei Strings bisher überhaupt keine Kodierungen, das sind letztlich einfach Byte-Arrays. Es gibt lediglich einige spezielle Funktionen, die mit Zeichenkodierungen umgehen können, die sind dann allerdings explizit anzugeben.

Ich habe die Verbindung zwischen PHP und MySQL mit Debian-Standardeinstellungen extra geprüft und bin dabei darauf gestoßen, dass zumindest bei der Nutzung von mysqli-Funktionen character_set_client, character_set_connection und character_set_results sogar anders als bei Nutzung des MySQL-Clients ebenfalls auf latin1 stehen. PHP bzw. dessen mysqli-Erweiterung bietet offenbar bisher keine Möglichkeit an, die Kodierung in der Konfiguration vorzugeben: - Unter wird dann auch wiederum empfohlen, ein SET NAMES utf8; abzusetzen, wofür man unter PHP eben mysqli_set_charset() verwenden sollte. Um Scripte nicht unnötig an eine bestimmte Umgebung zu binden, ist das vermutlich eh der beste Weg.

Korrekt ist natürlich, dass ein Editor unter einem System mit UTF-8-Locale auch UTF-8 verwenden wird, wenn man ihm nichts anderes vorgibt. Unter Windows muss man einen Editor in aller Regel erst entsprechend konfiguieren. Insofern sehe ich an dieser Stelle (aber in diesem Szenario auch nur dort) den von dir behaupteten Vorteil durch die Nutzung eines Linux-Systems.

Abschließend hier mal eine kleine Checkliste für den korrekten Betrieb einer Webanwendung mit PHP und MySQL:
  • PHP-Scripte UTF-8-kodiert speichern, sinnvollerweise ohne , sonst gibt es z. B. mit header() oder setcookie() Probleme. Nicht jeder Editor unter Windows ist dazu in der Lage. Im Zweifelsfall mit einem Hex-Editor prüfen, ob vor dem Byte für das erste Zeichen in der Datei noch die Bytefolge EF BB BF steht. Das ist dann eine unerwünschte BOM.
  • Nach jedem Verbindungsaufbau zur MySQL-Datenbank mit mysqli_set_charset(..., 'utf8'); die Kodierung für die Kommunikation mit dem MySQL-Server festlegen.
  • Beim Anlegen der Datenbanken/Tabellen darauf achten, die Kodierung (und Kollation) explizit anzugeben. Sonst wird (zuminest in der Stanardkonfiguration) für Strings latin1 und latin1_swedish_ci verwendet. Dieser Punkt ist wie erwähnt tückisch, weil man es nicht so schnell merkt, wenn man ihn vergisst.
 
Danke für die ausführlichen Infos.

Kennst du evtl. die Begründung dafür, dass sowohl MySQL als auch PHP in der Standardeinstellung latin1 verwenden? Wenn es dazu tatsächlich noch keine Diskussion gegeben haben sollte, könnte man ja mal einen Feature Request bei MySQL öffnen.

Soweit ich das noch bei PHP in Erinnerung hab (hab schon ca. 3 Jahre lang nichts mehr damit gemacht), wollten die ja mit Version 6 das ganze Unicode-Problem angehen.

Wikipedia meint dazu:

Wikipedia schrieb:
Ab Version 5.4 ist der Standardzeichensatz von ISO 8859-1 auf Unicode geändert worden.[16] Ziel ist außerdem die vollständige Unicode-Umsetzung aller Funktionen in PHP, die in PHP 5.4 noch nicht abgeschlossen ist.[17] Damit werden vor allem interne Probleme mit Sprachkonstrukten bei der Verarbeitung von Unicode gelöst. Um Standard-Zeichenkettenfunktionen zu nutzen, welche keine Parameter für den Zeichensatz besitzen, können durch das Überladen der entsprechenden Multibyte-Funktionen auf Unicode-Fähigkeit umgestellt werden.[1]
 
Warum MySQL ausgerechnet intern standardmäßig noch latin1 verwendet, ist mir unklar. Möglicherweise gäbe es hier durch utf8 irgendwelche Kompatibilitätsprobleme mit alten Anwendungen. Unter habe ich einen enstpechenden Bug gefunden, damals war allerdings wohl alles noch latin1. Es hat sich also möglicherweise schon etwas getan.

PHP kennt wie erwähnt so etwas wie eine Zeichenkodierung bisher grundsätzlich nicht, lediglich bei einigen Funktionen gibt es die Ausnahmen. Die Aussage in der Wikipedia bezüglich der erfolgten Änderung ist IMHO stark irreführend. Wenn man der benannten Quelle folgt, sieht man, dass es lediglich um das Verhalten von zwei einzelnen Funktionen geht, wobei sich für htmlspecialchars da effektiv eh nichts ändert. Alle von der Funktion gefilterten Zeichen werden schließlich in ISO-8859-1 und UTF-8 jeweils durch die gleichen Bytewerte abgebildet. Auch wurde bei den Funktionen nicht etwa der Zeichensatz auf Unicode geändert (die Erweiterung des korrekt nutzbaren Zeichenvorrats ist bloß eine Konsequenz aus der Änderung), sondern die Zeichenkodierung auf UTF-8.

Zu beachten ist übigens auch noch, dass latin1 im speziellen Kontext von MySQL nicht wie zu erwarten das gleiche ist wie ISO-8859-1, sondern zu windows-1252 equivalent ist: - Folglich gehen bei der Speicherung in latin1 z. B. das €-Zeichen oder typografische Anführungszeichen nicht verloren.
 
Zuletzt bearbeitet:
Zurück
Oben