Hallo Stefan,
das ist ein klassiches Problem. Und es heißt nicht Zeichensatz, sondern Zeichencodierung.
<explanation type="long">
Viele Texteditoren speichern ihre Dateien im Latin1-Zeichensatz, der pro Zeichen ein Byte belegt und damit genau 256 Zeichen darstellen kann.
Die Alternative ist Unicode, der Millionen von Zeichen unterstützt. Das geht natürlich nicht mit einem Byte pro Zeichen, deswegen gibt es für Unicode Regeln, wie man Unicode-Zeichen in Bytes gießt. Guckst Du Wiki.
Zumeist wird UTF-8 als Codierung für Unicode verwendet. Die "klassischen" ASCII Zeichen (Zeichencode 0-127) werden darin genau wie im Latin1 codiert, und alle anderen Zeichen belegen zwei bis vier Bytes (deren Wert immer über 127 liegt). Die deutschen Umlaute belegen zwei Bytes.
Wenn der Browser eine andere Codierung unterstellt als in der Textdatei vorhanden ist, werden die Umlaute falsch dargestellt.
Fehler 1 ist: Die Datei ist Unicode, aber der Browser glaubt, es sei Latin1. In diesem Fall findet man statt einem ü die Zeichen ü.
Fehler 2 ist: Die Datei ist Latin1, aber der Browser denkt, es sei Unicode. Nun findet er ein Byte vor, dessen Wert über 127 ist und denkt, es sei der Beginn einer UTF-8 Sequenz. Dahinter folgt aber ein normales Zeichen, d.h. der Browser erkennt eine falsche UTF-8 Sequenz, bricht die Decodierung ab und zeigt ein �.
Nach Deiner Beschreibung liegt Fehler 2 vor.
Woher weiß der Browser, ob er von Latin1 oder UTF8 auszugehen hat? Dafür gibt es drei Möglichkeiten:
- Der Webserver schicht einen Content-Type Header mit einer Charset-Angabe. Zum Beispiel:
Content-Type: text/html; charset=utf-8
- Die HTML Datei enthält in den ersten 1024 Bytes ein Meta-Element, das den Zeichensatz angibt
<meta charset="iso-8859-1">
- Der Browser betrachtet sich den Dateiinhalt und stellt eine qualifizierte Vermutung an. Diese Möglichkeit hatte ich zuerst ausgeschlossen, habe aber gerade etwas mit deinem Source auf meinem PC rumgespielt und zumindest Edge zeigt den Umlaut immer richtig.
Wie spielt nun PHP hinein?
PHP ist ein Programm, das die HTML Ausgabe an Hand des PHP Scripts generiert. Der Content-Type der generierten Antwort hat nichts mehr mit PHP zu tun, deswegen setzt PHP den Content-Type Header selbst. Die PHP-Direktive default_charset in der php.ini Datei bestimmt dabei den charset-Anteil des Content-Type Headers, solange nicht explizit anderes angegeben wird. Und der Standardwert für default_charset ist schon seit einigen PHP Versionen UTF-8
.
</explanation>
Lösung: Speichere deine Quelle als UTF-8.
Schwierigere, für neue Projekte nicht empfehlenswerte Lösung: Verwende die header-Funktion, um den Content-Type Header mit einer für Dich passenden charset-Angabe zu senden.
Rolf
--
sumpsi - posui - obstruxi