Stefan Peters: Anderer Zeichensatz wenn .html in .php umbenannt wird?

Guten Tag,

ich habe dieses Forum gefunden und hoffe, dass ich hier jemanden finde, der mir das Folgende erklären kann:

Ich habe eine einfache HTMl-Seite:

<!doctype html>
<html lang="de">
<head>
<title>Meine Testseite</title>
<link rel="stylesheet" type="text/css" href="standard.css">
</head>
<body>
<p>Sie können hier folgendes sehen...</p>
</body>
</html>

Alles wird im Browser korrekt angezeigt. Wenn ich jetzt nur die Endung der Datei in .php ändere, dann werden die deutschen Umlaute nicht mehr korrekt dargestellt. Stattdessen wird ein Rautesymbol mit Fragezeichen angezeigt.

Warum wird die PHP-Seite, die doch meinem Verständnis nach, den identischen Code an den Browser sendet anders dargestellt als die direkte HTML-Datei?

Mit ein ein paar Fragezeichen zu viel auf der Stirn,

Steff

  1. Offensichtlich wurde für PHP-Skripte kein oder ein falsches Charset konfiguriert.

    Die einfachste und sicher funktionierende Methode, dieses zu tun, ist eine Zeile ...

    <?php
    header('Content-Type: text/html; charset=utf-8');
    ?>
    

    vor der ersten Ausgabe.

    Gruß aus dem HomeSeeoffice.

    1. Offensichtlich wurde für PHP-Skripte kein oder ein falsches Charset konfiguriert.

      Die einfachste und sicher funktionierende Methode, dieses zu tun, ist eine Zeile ...

      <?php
      header('Content-Type: text/html; charset=utf-8');
      ?>
      

      vor der ersten Ausgabe.

      Das erklärt mir leider nicht, warum es einen Unterschied macht, ob .html oder .php, bzw. warum in der .html-Datei ein deutscher Umlaut direkt korrekt dargestellt wird, aber in der .php-Datei nicht. Scheinbar schiebt der PHP-Interpreter da dem Browser doch noch etwas unter? (Bspw. über 'default_charset = "UTF-8"' in der php.ini?)

      Klar kann ich auch über 'header' den Zeichensatz auf UTF-8 setzen (sollte ich womöglich auch), aber so werden deutsche Umlaute auch nicht korrekt dargestellt.

      Wie macht man das denn üblicherweise? UTF-8 nutzen und alle deutschen Umlaute immer über HTML-Umlaute ( bspw. &auml; ) darstellen lassen?

      Steff

      1. Hallo Stefan,

        UTF-8 nutzen

        Ja

        und alle deutschen Umlaute immer über HTML-Umlaute ( bspw. &auml; ) darstellen lassen?

        Nein - das widerspricht der "UTF-8 nutzen" Idee. Den Rest habe ich in meinem anderen Post erklärt.

        Rolf

        --
        sumpsi - posui - obstruxi
  2. 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
    1. Vielen lieben Dank Rolf, danke deiner ausfürliche Erklärung habe ich es jetzt verstanden und es lag tatsächlich daran, dass der verwendete Editor im Standard "Ansi" stehen hatte und nicht "UTF-8".

      Das allein hatte aber nicht ausgereicht, ich musste zusätzlich auch noch den Browser über den Content-Type zu verstehen geben, dass ich wirklich "UTF-8" haben möchte.

      Nachdem ich beides korrigiert habe, werden nun auch die deutschen Umlaute direkt korrekt ausgegeben.

      Nochmals vielen Dank.

      Steff

      1. Hallo Stefan,

        Das allein hatte aber nicht ausgereicht, ich musste zusätzlich auch noch den Browser über den Content-Type zu verstehen geben, dass ich wirklich "UTF-8" haben möchte.

        Das hängt auch etwas am Browser. Ich erinnere mich an das Geschrei, als die "Codierung auswählen" Funktion aus Chrome entfernt wurde. Google meinte in einem Anfall von Hybris, sie würden jetzt korrekt selbst erkennen, was die Codierung sei.

        Und er erkennen UTF-8 auch. Aber nicht an den Codefolgen, sondern am Byte Order Mark (BOM, diese drei Bytes am Anfang des Dokuments, die in Unicode ein Nullbreites Leerzeichen darstellen). Aber wer schreibt sein PHP schon so, dass vor dem <!doctype> noch ein BOM geschickt wird.

        Das Encoding im Content-Type mitzuteilen (oder im meta charset Element) ist die sicherste Lösung.

        Rolf

        --
        sumpsi - posui - obstruxi