Michael: Umlaute in MYSQL-Datenbank

Hallo zusammen,

ich habe ein Problem mit dem Schreiben von Umlauten in eine MYSQL-Datenbank: In einem Webformular gebe ich z.B. ein "ä" ein. Dieses wird in der MYSQL-Datenbank als "ä" gespeichert. Wenn ich vor Ausführen der INSERT-Anweisung den ins Formular eingegebenen Buchstaben mit utf8_decode konvertiere, wird korrekt als "ä" gespeichert.

Eine solche Konvertierung sollte aber gar nicht nötig sein, denn sowohl Formularseitig als auch Datenbankseitig scheint alles auf "utf8" eingestellt (siehe unten).

Hat jemand eine Idee, warum hier trotzdem eine Konvertierung notwendig ist, bzw. wie ich diese unschöne Konvertierung vermeiden kann?

Gibt es möglicherweise serverseitige Einstellungen, die meine Angaben übersteuert haben?

Grüße

Michael

Die absendende Website hat folgende Angabe im Kopfbereich:
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

Das Formular zum Erfassen der Daten hat folgende Angaben:
<form id="erfassungsformular" name="erfassungsformular" action="erfassung.htm" accept-charset="UTF-8" method="post">

Die Verbindung zur MYSQL-Datenbank wird wie folgt hergestellt:
$verbindung = mysqli_connect(host, user, passwd, db) or die;
mysqli_query("SET NAMES 'utf8'",$verbindung) OR print(mysqli_error());
mysqli_query("SET CHARACTER SET 'utf8'",$verbindung) OR print(mysqli_error());

Das Auslesen der Variablen in der Datenbank mit
SHOW VARIABLES LIKE "c%"
ergibt folgendes Ergebnis:

character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server utf8
character_set_system utf8
character_sets_dir /usr/share/mysql/charsets/
collation_connection utf8_general_ci
collation_database utf8_unicode_ci
collation_server utf8_general_ci
completion_type 0
concurrent_insert 1
connect_timeout 10

  1. Mahlzeit Michael,

    Gibt es möglicherweise serverseitige Einstellungen, die meine Angaben übersteuert haben?

    Möglicherweise: mit welchem Charset liefert der Webserver das Dokument aus (Rechtsklick -> Seiteninformationen)? Die Angabe im <meta>-Element sollte ja nur zum Tragen kommen, wenn der Browser dort keine Informationen findet.

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Hallo EKKi,

      unter Seiteninformationen steht:

      Kodierung: UTF-8
      text/html; charset=UTF-8

      Das scheint es dann auch nicht zu sein?

      Viele Grüße

      Michael

      Mahlzeit Michael,

      Gibt es möglicherweise serverseitige Einstellungen, die meine Angaben übersteuert haben?

      Möglicherweise: mit welchem Charset liefert der Webserver das Dokument aus (Rechtsklick -> Seiteninformationen)? Die Angabe im <meta>-Element sollte ja nur zum Tragen kommen, wenn der Browser dort keine Informationen findet.

      MfG,
      EKKi

  2. Hallo,

    In einem Webformular gebe ich z.B. ein "ä" ein. Dieses wird in der MYSQL-Datenbank als "ä" gespeichert.

    Ja, das ist der utf-8-Code für ä. Passt doch. Waum ist das für dich ein Problem? Wenn es nach dem Auslesen als "ä" angezeigt wird statt als "ä", dann passiert das nicht, weil es falsch in der Datenbank steht, sondern weil die Ausgabe das utf-8 Zeichen nicht versteht. Du musst also nur dafür sorgen, dass die Software, die es dann anzeigt, auch "weiß", dass es sich utf-8-codierte Zeichen handelt.

    Für die korrekte Anzeige im Browser reicht die Angabe im HTML-Meta-Tag  nicht aus, der Server muss es auch im HTTP-Header als utf-8 deklarieren.

    Gruß, Don P

    1. Hallo Don,

      na ja, ich schaue mir mit phpMyAdmin 3.3.1 die Datenbank an und sehe dann das "ä" als "ä". Ich erwarte aber, dass mir das "ä" auch als "ä" angezeigt wird. Die Kodierung der phpMyAdmin-Seite ist "UTF-8", das sollte dann doch klappen?

      Wo muss ich drehen, um serverseitig den HTTP-Header zu beeinflussen?

      Grüße

      Michael

      Hallo,

      In einem Webformular gebe ich z.B. ein "ä" ein. Dieses wird in der MYSQL-Datenbank als "ä" gespeichert.

      Ja, das ist der utf-8-Code für ä. Passt doch. Waum ist das für dich ein Problem? Wenn es nach dem Auslesen als "ä" angezeigt wird statt als "ä", dann passiert das nicht, weil es falsch in der Datenbank steht, sondern weil die Ausgabe das utf-8 Zeichen nicht versteht. Du musst also nur dafür sorgen, dass die Software, die es dann anzeigt, auch "weiß", dass es sich utf-8-codierte Zeichen handelt.

      Für die korrekte Anzeige im Browser reicht die Angabe im HTML-Meta-Tag  nicht aus, der Server muss es auch im HTTP-Header als utf-8 deklarieren.

      Gruß, Don P

      1. Hi,

        bitte sinnvoll zitieren, und nicht gedankenlos einfach alles!

        na ja, ich schaue mir mit phpMyAdmin 3.3.1 die Datenbank an und sehe dann das "ä" als "ä". Ich erwarte aber, dass mir das "ä" auch als "ä" angezeigt wird. Die Kodierung der phpMyAdmin-Seite ist "UTF-8", das sollte dann doch klappen?

        Was meinst du mit „die Kodierung der pma-Seite“?

        Du kannst auch beim pma einstellen, welche Verbindungskodierung verwendet werden soll. Wenn du die auf UTF-8 stehen hast, und dir dann aber ein ä nicht als solches angezeigt wird - dann hast du auch kein korrektes ä in UTF-8 in der Datenbank stehen.

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
        1. Was meinst du mit „die Kodierung der pma-Seite“?

          Hallo Chris,

          ich meine mit „Kodierung der pma-Seite“ das was mir angezeigt wird, wenn ich im Firefox die Seiteninformationen aufrufe.

          Grüße

          Michael

          1. Hi!

            ich meine mit „Kodierung der pma-Seite“ das was mir angezeigt wird, wenn ich im Firefox die Seiteninformationen aufrufe.

            Das ist das, was der PMA in Richtung Browser schickt. Da kann er senden was er will, und er könnte zur Not auch noch Umkodierungen vornehmen, die du so nicht mitbekommst. Auch das sagt weder etwas über die Daten im DBMS aus, noch bringt dir das irgendeine Information, die du in deinen Scripten nutzen kannst.

            Es ist zwar immer nett, wenn man anderswo abschauen kann, aber die Informationen, die der PMA liefert, nützen einem in der Regel ohne grundlegende Kenntnisse der Materie nichts weiter.

            Lo!

        2. Hi!

          na ja, ich schaue mir mit phpMyAdmin 3.3.1 die Datenbank an und sehe dann das "ä" als "ä". Ich erwarte aber, dass mir das "ä" auch als "ä" angezeigt wird.

          Wenn das nicht der Fall ist, dann ist der Fehler garantiert anderswo aufgetreten. Es wurden Daten übergeben ohne die richtige Kodierungsangabe ausgehandelt zu haben.

          Die Kodierung der phpMyAdmin-Seite ist "UTF-8", das sollte dann doch klappen?

          Das was der PMA so anzeigt ist größtenteils sein "Problem". Es beeinflusst (außer den systemglobalen Werten) keine Verbindungen anderer Clients.

          Du kannst auch beim pma einstellen, welche Verbindungskodierung verwendet werden soll. Wenn du die auf UTF-8 stehen hast, und dir dann aber ein ä nicht als solches angezeigt wird - dann hast du auch kein korrektes ä in UTF-8 in der Datenbank stehen.

          Beim Datenlesen handelt der PMA immer UTF-8 mit dem MySQL-Server aus, auch dann wenn man ihm auf seiner Starseite unter "Zeichensatz / Kollation der MySQL-Verbindung" etwas anderes einstellt. Diese Angabe gilt nur für die Richtung vom PMA zu MySQL.

          Lo!

  3. Hi!

    ich habe ein Problem mit dem Schreiben von Umlauten in eine MYSQL-Datenbank: In einem Webformular gebe ich z.B. ein "ä" ein. Dieses wird in der MYSQL-Datenbank als "ä" gespeichert.

    MySQL-Datenbanken sind ein Blackboxen. Wie etwas gespeichert ist, siehst du nicht. Selbst wenn du dir die Dateien mit einem Heyeditor ansiehst, weißt du noch lange nicht, wie die Daten nach einer Abfrage aussehen, weil sie dazu gegebenenfalls umkodiert werden.

    Wenn ich vor Ausführen der INSERT-Anweisung den ins Formular eingegebenen Buchstaben mit utf8_decode konvertiere, wird korrekt als "ä" gespeichert.

    Das bedeutet, dass MySQL annimmt, du sendest Latin1-Daten.

    Eine solche Konvertierung sollte aber gar nicht nötig sein, denn sowohl Formularseitig als auch Datenbankseitig scheint alles auf "utf8" eingestellt (siehe unten).

    Ja, wenn man es richtig macht.

    Hat jemand eine Idee, warum hier trotzdem eine Konvertierung notwendig ist, bzw. wie ich diese unschöne Konvertierung vermeiden kann?

    Richtig machen.

    Gibt es möglicherweise serverseitige Einstellungen, die meine Angaben übersteuert haben?

    Nein, ich vermute eher, dass du irgendwo einen Verbindungsaufbau übersehen hast und in den Fällen gar keine Angaben von dir dem MySQL-Server bekannt sind.

    Die absendende Website hat folgende Angabe im Kopfbereich:
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />

    Das ist eine mittelbare Angabe. Sie kann vom Webserver im HTTP-Header überschrieben werden. Prüfe lieber, wie die Daten wirklich aussehen, bevor du sie MySQL übergibst. bin2hex() geht dafür, url_enconde() lässt sich auch dafür missbrauchen (und ist leichter zu lesen als bin2hex()).

    Das Formular zum Erfassen der Daten hat folgende Angaben:
    <form id="erfassungsformular" name="erfassungsformular" action="erfassung.htm" accept-charset="UTF-8" method="post">

    accept-charset wird nicht von allen Browsern korrekt beachtet. Wichtiger ist deshalb, HTTP-Header und Meta-Angabe korrekt zu setzen.

    Die Verbindung zur MYSQL-Datenbank wird wie folgt hergestellt:
    $verbindung = mysqli_connect(host, user, passwd, db) or die;
    mysqli_query("SET NAMES 'utf8'",$verbindung) OR print(mysqli_error());
    mysqli_query("SET CHARACTER SET 'utf8'",$verbindung) OR print(mysqli_error());

    SET NAMES und SET CHARACTER SET überschreiben sich gegenseitig. Beide zu setzen ist unsinnig und zudem ist SET CHARACTER SET mit Vorsicht zu genießen. Lass beides weg und nimm lieber stattdessen mysqli_set_charset().

    Das Auslesen der Variablen in der Datenbank mit
    SHOW VARIABLES LIKE "c%"

    Das muss natürlich auch in der Verbindung erfolgen, die du untersuchen willst. Beispielsweise mit dem phpMyAdmin zu schauen, bringt dir für deine Verbindung gar nichts.

    Grundlegender Literaturtipp: SELFHTML-Wiki Themen:Zeichencodierung, besonders der MySQL-Abschnitt (und der zum Webserver).

    Lo!

    1. Hallo dedlfix,

      vielen Dank für die Anregungen, ich werde das morgen ausprobieren bzw. nachlesen.

      Aktuell habe ich noch eine Frage zu diesem hier:

      Das Auslesen der Variablen in der Datenbank mit
      SHOW VARIABLES LIKE "c%"

      Das muss natürlich auch in der Verbindung erfolgen, die du untersuchen willst. Beispielsweise mit dem phpMyAdmin zu schauen, bringt dir für deine Verbindung gar nichts.

      Wie mache ich das konkret: Auslesen der Variablen in der Verbindung?

      Grüße

      Michael

      1. Hi!

        SHOW VARIABLES LIKE "c%"
        Das muss natürlich auch in der Verbindung erfolgen, die du untersuchen willst.
        Wie mache ich das konkret: Auslesen der Variablen in der Verbindung?

        Du öffnest eine Verbindung (z.B. mysqli_connect(), wenn du willst auch noch mysqli_set_charset()) und setzt darüber dieses SQL-Statement ab. Dann kannst du über diese Verbindung eine Aussage treffen, aber nicht in jedem Fall auf andere Verbindungen schließen.

        Lo!

        1. Hallo dedlfix,

          jetzt klappt es. Durch das Auslesen der Variablen in der Verbindung mit

          $resultat= mysqli_query($verbindung, "SHOW VARIABLES LIKE 'c%'");

          while ($row = mysqli_fetch_array($resultat))
          {
          print ("<p>".$row[0].": ".$row[1]."</p>");
          }

          hat sich gezeigt, dass die Verbindung "latin1" codiert war.

          Mit mysqli_set_charset($verbindung , "utf8"); konnte ich das Ganze auf utf8 umstellen, so dass es nun so funktioniert wie ich es möchte.

          Vielen Dank an Dich und alle die auf meine Frage geantwortet hatten.

          Grüße

          Michael