Peder: UTF-8 und MySQL

Hallo,

Programmiere grade ne Homepage und nun habe ich eine Seite integriert die den Content von der Datenbank abruft.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
(Charset steht auf Automatisch im FF)

Der Text der über die Datenbank abgerufen wurde, wird korrekt dargestellt und der restliche text (NUR auf dieser Seite) mit Sonderzeichen (öäa).
Mit der selben Einstellung auf den anderen Seiten läuft es auch sauber aber komischer weise obwohl kein Content von der Datenbank abgerufen wird.
D.h., um das mal zu verstehen, der Browser merkt ah da sind 2 verschiedene Charsets in einem Dokument und muss sich für eins entscheiden, oder?
Obwohl ich aber in der Datenbank öäü und im eigentlichen .php-file welches Inkludiert wird Sonderzeichen im Klartext verwendet habe.

Gebe ich nun Explizit folgendes Charset an:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

Dann verhält sich das folgendermaßen:
Obwohl die Datenbank ebenfalls auf UTF-8 eingestellt ist werden die Umlaute als Sonderzeichen (�) dargestellt und der Rest korrekt. also genau umgekehrt. Die anderen Seiten die nichts mit der DB zu tun haben laufen immer korrekt. Es gibt also nur Probleme wenn ich beide Formen mische.

Warum?
Peder

  1. Hallo nochmal,

    Die Lösung habe ich gefunden
    http://de3.php.net/manual/de/function.utf8-encode.php

    aber die Erkenntnis, also die Antwort auf die Frage Warum, fehlt mir noch.

    Peder

    1. Hallo,

      Die Lösung habe ich gefunden
      http://de3.php.net/manual/de/function.utf8-encode.php

      aber die Erkenntnis, also die Antwort auf die Frage Warum, fehlt mir noch.

      Peder

      Ich finde, Du zäumst hier das Pferd von hinten auf. Besser wäre es, die Daten im gewünschten Charset in der Datenbank zu speichern, anstatt sie mit PHP im nachhinein nach UTF-8 zu codieren.
      Du musst auf folgendes achten:

      1. Wenn die Daten aus einem HTML Formular stammen, dann muss das HTML Dokument auch als UTF-8 erkannt werden. Dabei hilfreich wäre der meta-tag:
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">,
      oder bei xHTML Dokumenten der Prolog
      <?xml version="1.0" encoding="utf-8"?> => allerdings taucht hier der IE6 in den Quirksmode ab.

      2. Nachdem die Datenbankverbindung hergestellt wurde, definierst Du den Charset für die Verbindung explizit auf utf8. Je nach MySQL Version mit:
      mysql_set_charset("utf8", [ressource $db_link)
      oder bei älteren Version (<5 glaube ich)
      mysql_query("SET NAMES utf8", [ressource $db_link);

      3. Beim erstellen der Tabellen gibst Du auch deren Charset an, z.B.:

        
      CREATE table IF NOT EXISTS tablename(  
            Foo VARCHAR(20),  
            Bar TEXT  
          ) CHARACTER SET utf8 COLLATE utf8_general_ci;  
      
      

      4. Das HTML Dokument, in welchem die Daten angezeigt werden sollen, muss ebenfalls wie in Punkt eins beschrieben mit Charset UTF-8 angezeigt werden.

      Wenn diese 4 Schritte konsistent durchgezogen werden, dann klappt's auch mit den Umlauten.

      netten Tag
      ^da Powl

      --
      ===============================
      powl.hat-gar-keine-homepage.de/
      1. echo $begrüßung;

        Dabei hilfreich wäre der meta-tag:
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">,
        oder bei xHTML Dokumenten der Prolog
        <?xml version="1.0" encoding="utf-8"?>

        Ein kurzer Versuch mit XML-Prolog auf UTF-8 und dem Meta-Element auf ISO-8859-1 gestellt, dazu einen HTTP-Content-Type "text/html" ohne charset-Zusatz, ergibt im Firefox ISO-8859-1. Der XML-Prolog ist da also nicht maßgebend, so wie es aussieht.
        Was aber auf alle Fälle Vorrang hat ist der charset-Zusatz im HTTP-Header Content-Type.

        1. Nachdem die Datenbankverbindung hergestellt wurde, definierst Du den Charset für die Verbindung explizit auf utf8. Je nach MySQL Version mit:
          mysql_set_charset("utf8", [ressource $db_link)

        Das ist auch von der PHP-Version abhängig. Erst seit 5.2.3 gibt es diese Funktion. Das mysqli-Pendant dazu gibt es schon seit Version 5.0.5. Mit der 4er Reihe von PHP bleibt aber nur SET NAMES (besser: Umsteigen auf 5).

        oder bei älteren Version (<5 glaube ich)
        mysql_query("SET NAMES utf8", [ressource $db_link);

        Konkret: MySQL 5.0.7 und 4.1.13. Diese alten Versionen sollte man in freier Wildbahn aber nicht mehr antreffen. Allerdings gibt es noch 4.0 und gelegentlich 3.x, die komplett ausgeschlossen sind.

        1. Beim erstellen der Tabellen gibst Du auch deren Charset an, z.B.:

        Das ist nur ein Default-Wert für Felder, deren Kodierung nicht explizit angegeben wurde. Jedes Feld kann seine eigene Kodierung und/oder Kollation haben. Und die ist am Ende maßgebend.

        echo "$verabschiedung $name";

  2. echo $begrüßung;

    Programmiere grade ne Homepage und nun habe ich eine Seite integriert die den Content von der Datenbank abruft.
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    Der Doctype ist komplett uninteressant für Zeichenkodierungsprobleme.

    (Charset steht auf Automatisch im FF)

    Der Browser richtet sich immer nach den Angaben des Webservers, wenn im HTTP-Header Content-Type eine charset-Angabe mitgegeben wurde. Fehlt diese versucht er

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    dieses Meta-Element auszuwerten. Der Firefox beispielsweise zeigt über Rechtsklick (Kontextmenü) Seiteninformation (bzw. Frame-Information bei Frames-Seiten) an, mit welcher Kodierung er die Seite zu interpretieren versucht. Es gibt auch die livehttpheaders-Extension, mit der sich die Response-Header ansehen lassen, um die HTTP-Header-Angaben zu prüfen.

    Der Text der über die Datenbank abgerufen wurde, wird korrekt dargestellt und der restliche text (NUR auf dieser Seite) mit Sonderzeichen (öäa).

    Sieht aus, als ob die Seite gerade mit Latin1/ISO-8859-1/Win-1252 interpretiert wird, der "restliche Text" aber UTF-8-kodiert ist.

    D.h., um das mal zu verstehen, der Browser merkt ah da sind 2 verschiedene Charsets in einem Dokument und muss sich für eins entscheiden, oder?

    Der Browser rät nur dann, wenn er keine der beiden charset-Angaben findet.

    Obwohl ich aber in der Datenbank öäü und im eigentlichen .php-file welches Inkludiert wird Sonderzeichen im Klartext verwendet habe.

    Die entscheidende Frage ist immer, in welcher Kodierung diese Zeichen vorliegen und wie das Programm, mit dem du die Zeichen anschaust, sie interpretiert.

    Obwohl die Datenbank ebenfalls auf UTF-8 eingestellt ist ...

    Es gibt beim MySQL-Server insgesamt 10 verschiedenartige Stellen, an denen eine Kodierung eingestellt werden kann. Die beiden wichtigsten sind die Kodierung der einzelnen Felder und die Kodierung auf der Verbindung zu Clients. Letztere wird mit der MySQL-API-Funktion mysql_set_character_set() festgelegt. Zu dieser Funktion gibt es auch Pendants in anderen APIs. Eine Alternative wäre SET NAMES, beschrieben auf der vorher verlinkten Seite.

    ... werden die Umlaute als Sonderzeichen (�) dargestellt und der Rest korrekt.

    Das wird an der Default-Einstellung Latin1 liegen. Wenn du UTF-8 auf deiner Verbindung haben möchtest, dann sag der das nach dem Öffnen. Wenn du im Browser unter dem Menüpunkt Ansicht (Zeichen-)kodierung mal auf ISO-8859-1 bzw. Win-1252 umstellst, wirst du sicher sehen, dass dann die Datenbankumlaute richtig dekodiert werden können.

    echo "$verabschiedung $name";