Ralf König: Umlaute werden zu ?

Apache/mySQL/HTML/PHP

Wenn ich über meine (selbst zurechtgezimmerte) Webseite in einem Formular Texte erfasse, dann werden verwendete Umlaute bei späterer Ausgabe oft als *?* dargestellt.

Ich vermute, es hat irgendetwas mit den DB-Einstellungen oder mit den Meta-Angaben (nennt man so, oder?) im Head meiner Seite/n zu tun. Unschwer zu erkennen: Ich habe von sowas keine Ahnung! *Ein Wunder, dass ich meine Seiten überhaupt soweit zum Laufen gebracht habe :-) ...

Habe inzwischen schon einige Stunden hierzu rumgegoogelt, habe etwas über Kollation und Latin und UTF-8 usw. gelesen - jedoch scheint mir, das ganze ist ein großes Thema - auf die Schnelle kaum zu erfassen :-( ...

Ob denn wohl jemand so kompetent/freundlich ist, mir zu sagen, welche Einstellungen ich wo genau vornehmen muss (Kollation der DB? Kollation der Tabellenspalten? In meinen Webseiten? so dass deutschsprachige Besucher Umlaute und keine *?* mehr zu sehen bekommen?!

Herzlichen Dank!

  1. Hi,

    Ob denn wohl jemand so kompetent/freundlich ist, mir zu sagen, welche Einstellungen ich wo genau vornehmen muss (Kollation der DB? Kollation der Tabellenspalten? In meinen Webseiten? so dass deutschsprachige Besucher Umlaute und keine *?* mehr zu sehen bekommen?!

    dedlfix hat sich hier schon des öfteren umfassend mit dem Thema auseinandergesetzt - wenn du ihn bei der Archivsuche als Autor angibst, findest du bestimmt genügend Beiträge von ihm, die keine Fragen mehr offen lassen sollten.

    Bspw. </archiv/2009/1/t182289/#m1206179>

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
  2. moin,

    Ob denn wohl jemand so kompetent/freundlich ist, mir zu sagen, welche Einstellungen ich wo genau vornehmen muss (Kollation der DB? Kollation der Tabellenspalten? In meinen Webseiten? so dass deutschsprachige Besucher Umlaute und keine *?* mehr zu sehen bekommen?!

    Fang mit HTTP und HTML an.
    HTTP: Angabe des Content-Type; charset im Header
          Konfiguration des Webservers, .htaccess
          DefaultCharset des Webservers
    HTML: Deklaration charset im Header der HTML-Datei

    Lerne Deinen Editor kennen: Mit welcher Kodierung speicherst Du Text/Html-Dateien.

    Benutze http://validator.w3.org um Fehler mit Zeichenkodierung zu finden.

    Viele Grüße,
    Horst Haselhuhn

  3. Also, ich habe jetzt alles auf UTF-8 umgestellt; meine DB, die Tabellen, Spalten, die Dateien (dort UTF-8 ohne BOM, weil php-Sessions) und habe im Head meiner Seite/n

    meta http-equiv="Content-Type" content="text/html; text/html; charset=UTF-8

    eingetragen. Hoffe, damit ist nun gut! :-) Zumindest werden Umlaute nun korrekt angezeigt.

    Allerdings sehen nun die Einträge in meiner DB anders aus: Aus dem Wort *körperliche* ist nun *körperliche* geworden - auf der Webseite wirds aber korrekt angezeigt. Ist das normal so?

    1. Hi!

      Also, ich habe jetzt alles auf UTF-8 umgestellt; meine DB, die Tabellen, Spalten, die Dateien (dort UTF-8 ohne BOM, weil php-Sessions) und habe im Head meiner Seite/n

      In deiner Aufzählung fehlt die Kodierung der Verbindung zwischen DBMS und PHP. (Stichwörter: mysql_set_charset() oder SET NAMES)

      Allerdings sehen nun die Einträge in meiner DB anders aus: Aus dem Wort *körperliche* ist nun *körperliche* geworden - auf der Webseite wirds aber korrekt angezeigt. Ist das normal so?

      Da vermutlich keine Verbindungskodierung eingestellt wurde, geht MySQL von Latin1 aus und kodiert den ankommenden Bytestrom in die Feldkodierung um. Rückwärts macht es das umgekehrt und du siehst wieder UTF-8. Normal ist das nicht, denn dabei geht dir Funktionalität (Stringfunktionen, Sortierung und Vergleiche arbeiten nicht richtig) und Spicherplatz (je ein Zeichen für jedes UTF-8-Byte) verloren. Die Folge ist unkorrektes Arbeiten und Datenverlust.

      Lo!

      1. Da vermutlich keine Verbindungskodierung eingestellt wurde, geht MySQL von Latin1 aus und kodiert den ankommenden Bytestrom in die Feldkodierung um. Rückwärts macht es das umgekehrt und du siehst wieder UTF-8. Normal ist das nicht, denn dabei geht dir Funktionalität (Stringfunktionen, Sortierung und Vergleiche arbeiten nicht richtig) und Spicherplatz (je ein Zeichen für jedes UTF-8-Byte) verloren. Die Folge ist unkorrektes Arbeiten und Datenverlust.

        Lt.phpMyAdmin ist:
        Zeichensatz / Kollation der MySQL-Verbindung: utf-8_general_ci
        eingestellt.

        Daran kann es also nicht liegen - oder bringe ich da was durcheinander?

        1. Hi!

          Lt.phpMyAdmin ist:
          Zeichensatz / Kollation der MySQL-Verbindung: utf-8_general_ci
          eingestellt.

          Das ist die Kodierung, die der PMA auf seinen Verbindungen verwendet. Sie sagt nichts über den Defaultwert und schon gar nichts über Verbindungen anderer Client aus.

          Schau im PMA auf der Seite "MySQL-System-Variablen anzeigen" die Werte für "character set ..." an, speziell für client, connection und results und da jeweils die globalen Werte (wenn angezeigt). Das sind die für dich relevanten, wenn du selbst keine aushandelst.

          Daran kann es also nicht liegen - oder bringe ich da was durcheinander?

          Darin (also an obiger Information) liegt die Ursache deines Problems nicht, weil der Wert für dich uninteressant ist. Stell einfach ganz konkret deine Verbindung so ein, wie dein Client sie braucht. Verlass dich nicht auf irgendwelche Defaultwerte.

          Lo!

          1. Schau im PMA auf der Seite "MySQL-System-Variablen anzeigen" die Werte für "character set ..." an, speziell für client, connection und results und da jeweils die globalen Werte (wenn angezeigt).

            haracter set client   utf8
            (Globaler Wert) latin1
            character set connection utf8
            (Globaler Wert) latin1
            character set database latin1
            character set results utf8
            (Globaler Wert) latin1
            character set server latin1
            character set system utf8
            character sets dir /usr/local/mysql/share/mysql/charsets/
            collation connection utf8_general_ci
            (Globaler Wert) latin1_swedish_ci
            collation database latin1_swedish_ci
            collation server latin1_swedish_ci

            Stell einfach ganz konkret deine Verbindung so ein, wie dein Client sie braucht. Verlass dich nicht auf irgendwelche Defaultwerte.

            mysql_set_charset() fällt für mich leider aus, da php 5.xx benötigt wird, mein provider dies aber nur als cgi-version(?) anbietet ...

            1. Hi!

              Schau im PMA auf der Seite "MySQL-System-Variablen anzeigen" die Werte für "character set ..." an, speziell für client, connection und results und da jeweils die globalen Werte (wenn angezeigt).

              haracter set client   utf8
              (Globaler Wert) latin1
              character set connection utf8
              (Globaler Wert) latin1
              character set results utf8
              (Globaler Wert) latin1

              Sag ich ja, MySQL nimmt zu deiner Verbindung an, sie laufe mit Latin1. Das ist dein Problem.

              Stell einfach ganz konkret deine Verbindung so ein, wie dein Client sie braucht. Verlass dich nicht auf irgendwelche Defaultwerte.
              mysql_set_charset() fällt für mich leider aus, da php 5.xx benötigt wird, mein provider dies aber nur als cgi-version(?) anbietet ...

              CGI oder nicht ist keine Frage der Version. Wenn dein Hoster kein PHP 5 anbietet, solltest du ihn wechseln. PHP 4 ist schon seit einer ganzen Weile eingestellt. Mitunter ist es jedoch nur eine Frage der Konfiguration, dass man sein Paket oder bestimmte Verzeichnisse so umkonfiguriert, dass PHP5 verwendet wird. Frag mal die Support-Seiten deines Hosters oder ihn selbst.

              Wenn dir nun immer noch kein mysql_set_charset() zur Verfügung steht, dann gibt es noch die Variante, ein SET NAMES-Statement nach dem Verbindungsaufbau abzusetzen. Die ist nicht ganz so perfekt wie die genannte Funktion, aber für Latin1/ISO-8859-1 und UTF-8 problemlos verwendbar.

              Lo!

      2. Da vermutlich keine Verbindungskodierung eingestellt wurde, geht MySQL von Latin1 aus und kodiert den ankommenden Bytestrom in die Feldkodierung um. Rückwärts macht es das umgekehrt und du siehst wieder UTF-8. Normal ist das nicht, denn dabei geht dir Funktionalität (Stringfunktionen, Sortierung und Vergleiche arbeiten nicht richtig) und Spicherplatz (je ein Zeichen für jedes UTF-8-Byte) verloren. Die Folge ist unkorrektes Arbeiten und Datenverlust.

        Ich habe meine db_connect.php um die letzten zwei Zeilen ergänzt:

        <?php  
        $dbHost = "localhost";  
        $dbUser = "ww5231";  
        $dbPass = "XXXXXX";  
        $dbName = "urw_ww5231";  
          
        $connect = mysql_connect($dbHost, $dbUser, $dbPass) or die("keine verbindung");  
          
        $selectDB = mysql_select_db($dbName, $connect) or die ("keine datenbank");  
          
        mysql_query("SET NAMES 'utf8'");  
        mysql_query("SET CHARACTER SET 'utf8'");  
        ?>
        

        Seither werden Umlaute auf der Website, als auch in der DB richtig dargestellt.

        Ist das denn nun so richtig?

        1. Hi!

          mysql_query("SET NAMES 'utf8'");
          mysql_query("SET CHARACTER SET 'utf8'");
          Ist das denn nun so richtig?

          Jein. Bitte die zweite Zeile streichen. Beide Statements ändern die selben drei Einstellungen, das aber unterschiedlich. Sie überschreiben sich also gegenseitig, und die Wirkung von SET CHARACTER SET will man nur dann haben, wenn man sie genau kennt und bewusst einsetzt. Bei unsachgemäßer Anwendung kann es zu Datenverlust kommen. Mit SET NAMES passiert das nicht.

          Connection Character Sets and Collations

          Lo!

    2. hi,

      Also, ich habe jetzt alles auf UTF-8 umgestellt; meine DB, die Tabellen, Spalten, die Dateien (dort UTF-8 ohne BOM, weil php-Sessions) und habe im Head meiner Seite/n

      meta http-equiv="Content-Type" content="text/html; text/html; charset=UTF-8[/code]

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

      Allerdings sehen nun die Einträge in meiner DB anders aus: Aus dem Wort *körperliche* ist nun *körperliche* geworden - auf der Webseite wirds aber korrekt angezeigt. Ist das normal so?

      Wenn Deine "Betrachter"(*) eine unterschiedliche Zeichenkodierung verwenden, Ja.

      (*) einer der Beiden ist der Browser. Check mal, was fürne Codierung der Andere benutzt.

      Viele Grüße
      Horst Haselhuhn