dedlfix: Zeichenkodierung

Beitrag lesen

Hi!

Link zum Problemkind?
http://tdv.td.ohost.de/AbwesiImage/site/

Mit der Firefox-Extension livehttpheaders sehe ich den HTTP-Header Content-Type mit einem charset-Parameter utf-8. Auch gibt es ein gleichnamiges Meta-Element mit der selben charset-Angabe. Diese wird aber beim Vorhandensein der Angabe im HTTP-Header nicht verwendet (darf nicht, der HTTP-Header hat eine höhere Priorität).

Das Dokument selbst beginnt mit einer BOM (Byte-Order-Markierung). Das sieht man, wenn man sich die Quelltextansicht nimmt und dort die Zeichenkodierung auf ISO-8859-1 stellt. Dann wird das Dokument gemäß dieser Kodierung zu lesen versucht und man sieht die typische Sequenz  am Anfang. Die BOM wird nicht benötigt, Windows' Notepad fügt sie beim Speichern als "UTF-8" ungefragt ein. Nimm einen Editor, der die BOM weglassen kann, beispielsweise Notepad++.

Man sieht es z.B. im Menü, da das ü nicht richtig dargestellt wird.
Und beim "Editor" bei textgröße [ö und ß], sowie wenn man Unicode-Zeichen eingibt und auf Vorschau klickt =/

Das title-Element hat als Inhalt einen "Frontalzusammenstoß", der UTF-8-kodiert ist. Dann kommt irgendwann das "Menü", das aber ISO-8859-1-kodiert ist, ebenso "textgröße". Fügst du Dokumente zusammen? Dann sind diese anscheinend unterschiedlich kodiert. Wenn die Daten aus MySQL kommen, dann verhandelst du vielleicht nicht die gewünschte Kodierung.

Das erkennt man, wenn man die Zeichenkodierung zwischen UTF-8 und ISO-8859-1 wechselt. Mal ist das eine richtig zu sehen, mal das andere. Da ISO-8859-1 eine Ein-Byte-Kodierung ist, sieht man für jedes Byte einer UTF-8-Sequenz ein eigenes Zeichen. Anders gesagt: Jedes Byte der UTF-8-Sequenz wird gemäß ISO-8859-1 gelesen als eigenes Zeichen interpretiert (und dargestellt). Hingegen folgen die Bytes einer UTF-8-Sequenz bestimmten Regeln, die üblicherweise durch die normale Verwendung von ISO-8859-1-kodierten Umlauten und dergleichen nicht eingehalten wird. Ergebnis ist dann das Darstellen des Ersatzzeichens � und manchmal auch das "Verschlucken" eines oder mehrerer nachfolgender Bytes, die für den Erkennungsversuch der UTF-8-Sequenz draufgehen.

Und was mir noch auf gefallen ist, sobald ich utf-8 angegeben hab, werden Zeilenumbrüche nicht mehr mit <br> ersetzt.
$text = preg_replace("/\n/","<br>\n",$text);
Auch folgender Aufruf brachte mir nicht mehr das gewünschte Ergebnis:
$text = nl2br($text);

Die Angeben im HTTP-Header oder Meta-Element haben keinen Einfluss auf die Arbeitsweise PHPs. Lediglich preg_replace() kann mit UTF-8-kodierten Texten umgehen, wenn du den entsprechenden Modifizierer angibst. Das ist aber auch unabhängig von den beiden genannten Angaben. Jedenfalls kann ich derzeit keine Ursache für dieses Verhalten sehen. Wenn du dafür die Ursache suchen willst, lass dir genau anzeigen, was du bekommst/hast und was nach dem Ersetzen rausgekommen ist. Dazu schaut man sich am besten die Bytes an, was mit bin2hex() geht, aber auch url_encode() lässt sich dafür sehr gut missbrauchen. Dessen Ergebnis ist etwas einfacher zu lesen, weil es die ASCII-Buchstaben und Ziffern nicht "verhext".

Lo!