lxuser: Perl / MySQL Kodierungsprobleme

Hallo,

Ich hab das Problem das werte die aus meiner MySQL Datenbank nicht in UTF-8 beim Perl Script ankommen.

Auf der gesamten Seite gibt es keinerlei kodierungsprobleme und ich hab im head UTF-8 angegeben.
<meta charset="utf-8">

Außerdem hab ich bei dem Befehl zum herstellen der Verbindung auch UTF-8 angegeben.

my $datenbank_bandnamen = DBI->connect("DBI:mysql:database=$db_name", $db_user, $db_pass, {mysql_enable_utf8 => 1});

Desweiteren hab ich beim phpMyAdmin bei "Zeichensatz/Kollation der MySQL-Verbindung" auch utf8_unicode_ci angebenen und das gleiche auch bei sämtlichen Tabellen bei allen werten utf8_unicode_ci.
Trotzdem erscheint immer bei den umlauten dieses Fragezeichen...

Mir gehen da langsam die Ideen aus :(

Hoffe ihr könnt mir weiterhelfen.

Freundliche grüße und danke im voraus.

Martin

  1. <meta charset="utf-8">

    Das nützt "nicht immer". Meist halt nur beim lokalen Öffnen. Gibt es denn einen HTTP-Header?

    print "Content-Type: text/html; charset=UTF-8\n\n";

    Oder ist gar sicher, dass nur die Daten aus der Datenbank verkorkst ankommen?

    Jörg Reinholz

    1. Hi,

      <meta charset="utf-8">

      Das nützt "nicht immer". Meist halt nur beim lokalen Öffnen. Gibt es denn einen HTTP-Header?

      Und als Ergänzung: wird auch wirklich UTF-8 verwendet?
      (es nützt nichts, auf ein rotes Auto draufzuschreiben "dieses Auto ist gelb" ...)

      cu,
      Andreas

      Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.

      -- Warum nennt sich Andreas hier MudGuard?
      O o ostern ...
      1. Hallo,

        (es nützt nichts, auf ein rotes Auto draufzuschreiben "dieses Auto ist gelb" ...)

        (naja, wenn du es mit gelber Farbe machst und sowohl groß genug als auch fett genug...

        Gruß
        Kalk)

    2. <meta charset="utf-8">

      Das nützt "nicht immer". Meist halt nur beim lokalen Öffnen. Gibt es denn einen HTTP-Header?

      print "Content-Type: text/html; charset=UTF-8\n\n";

      Oder ist gar sicher, dass nur die Daten aus der Datenbank verkorkst ankommen?

      Jörg Reinholz

      Die UTF-8 Kodierung funktioniert wohl ich kann auch kyrillische Buchstaben auf meiner Seite sehen.
      Das hängt irgendwie mit MySQL zusammen da kommt nur latin1 raus.
      Wenn ich das HTML chatset auf latin1 stelle sehe ich auch die umlaute die aus der MySQL Datenbank kommen korrekt.

      Danke für den tipp mit dem Header das hab ich auch gleich mal umgesetzt :)
      Das Problem besteht aber natürlich immer noch

      1. Das hängt irgendwie mit MySQL zusammen da kommt nur latin1 raus.

        Soso. Welcher Meinung hinsichtlich der eingestellten Kodierung ist denn Perl?

        Die Ausgaben von

        #!/usr/bin/perl print "Content-Type: text/html; charset=UTF-8\n\n"; print "<pre>\n"; foreach(keys(%ENV)) {   print "$ENV{$_}\n"; }

        könnten von erheblichen Interesse sein. Wie man dann eingreift hängt eventuell davon ab, ob Perl als CGI oder als Modul ausgeführt wird.

        Du musst das auch in der Umgebung testen, die das später laufende Perl-Skript hat. Es kann nämlich sein, dass Du als Benutzer ETWAS WIE LANG=de_DE.utf-8 i, Profil (~/.profile) stehen hat, der Apache(?) das Perl aber mit ETWAS WIE LANG=en_EN.cp1252 startet.

        Das hat die Folge, dass Perl im Terminal und Perl in der Apache-Umgebung verschiedene Ergebnisse liefern. Ich hoffe ja, Du benutzt nicht so was wie XAMPP.

        Jörg Reinholz

        1. #!/usr/bin/perl print "Content-Type: text/html; charset=UTF-8\n\n"; print "<pre>\n"; foreach(keys(%ENV)) {   print "ENV{$_}:\t$ENV{$_}\n"; }
          1. #!/usr/bin/perl print "Content-Type: text/html; charset=UTF-8\n\n"; print "<pre>\n"; foreach(keys(%ENV)) {   print "ENV{$_}:\t$ENV{$_}\n"; }

            Hier die Ausgaben... von char Kodierung seh ich da allerdings nichts.

            ENV{SCRIPT_NAME}: /cgi-bin/test.pl
            ENV{SERVER_NAME}: XXXXX.de
            ENV{SERVER_ADMIN}: webmaster@XXXXX.de
            ENV{HTTP_ACCEPT_ENCODING}: gzip, deflate
            ENV{HTTP_CONNECTION}: keep-alive
            ENV{REQUEST_METHOD}: GET
            ENV{HTTP_ACCEPT}: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            ENV{SCRIPT_FILENAME}: /home/XXXXX/public_html/cgi-bin/test.pl
            ENV{CONTEXT_PREFIX}: /cgi-bin/
            ENV{REQUEST_SCHEME}: http
            ENV{SERVER_SOFTWARE}: Apache
            ENV{QUERY_STRING}:
            ENV{REMOTE_PORT}: 45342
            ENV{HTTP_USER_AGENT}: Mozilla/5.0 (X11; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0
            ENV{SERVER_PORT}: 80
            ENV{SERVER_SIGNATURE}:
            ENV{HTTP_ACCEPT_LANGUAGE}: en-ca
            ENV{REMOTE_ADDR}: 5.147.206.238
            ENV{CONTEXT_DOCUMENT_ROOT}: /home/XXXXX/public_html/cgi-bin/
            ENV{SERVER_PROTOCOL}: HTTP/1.1
            ENV{PATH}: /usr/local/bin:/usr/bin:/bin
            ENV{REQUEST_URI}: /cgi-bin/test.pl
            ENV{GATEWAY_INTERFACE}: CGI/1.1
            ENV{SERVER_ADDR}: 198.30.107.43
            ENV{DOCUMENT_ROOT}: /home/XXXXX/public_html
            ENV{HTTP_HOST}: XXXXX.de
            ENV{UNIQUE_ID}: VHsL4MMeaysADlSBdrUAAABP

  2. Moin Moin!

    Du hast Browser und DB überzeugt, UTF8 zu benutzen. Fehlt nur noch Perl.

    UTF8-Flag (blöder, weil fehlleitender Name!) bei den an DBI übergebenen Strings gesetzt? Sprich: ist utf8::is_utf8($text)==1?

    Wenn nicht, brauchst Du Encode, um die Bytes vom Webserver in einen UTF8-String umzusetzen. Wenn Du das CGI-Modul benutzt, erledigt das das Pragma -utf8, sprich: Du bindest CGI mit use CGI qw( -utf8 ); ein.

    Sieh Dir mal die Tests 40UnicodeRoundTrip.t und 41Unicode.t aus DBD::ODBC an, dann wird das hoffentlich etwas klarer.

    perlunitut, perlunifaq und perlunicode solltest Du gelesen und verstanden haben.

    Alexander

    -- Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
    1. Moin Moin!

      Du hast Browser und DB überzeugt, UTF8 zu benutzen. Fehlt nur noch Perl.

      UTF8-Flag (blöder, weil fehlleitender Name!) bei den an DBI übergebenen Strings gesetzt? Sprich: ist utf8::is_utf8($text)==1?

      Wenn nicht, brauchst Du Encode, um die Bytes vom Webserver in einen UTF8-String umzusetzen. Wenn Du das CGI-Modul benutzt, erledigt das das Pragma -utf8, sprich: Du bindest CGI mit use CGI qw( -utf8 ); ein.

      Sieh Dir mal die Tests 40UnicodeRoundTrip.t und 41Unicode.t aus DBD::ODBC an, dann wird das hoffentlich etwas klarer.

      perlunitut, perlunifaq und perlunicode solltest Du gelesen und verstanden haben.

      Alexander

      Uff Danke.
      Da muss ich erstmal n kopf für haben um das alles zu lesen bin grad krank da fällt mir das etwa schwer..

      1. Da muss ich erstmal n kopf für haben um das alles zu lesen bin grad krank da fällt mir das etwa schwer..

        du bist krank, programmierst aber gerade, und lesen fällt dir schwer? wie willst du da programmierfehler entdecken?

        druck dir den link, den ich unten gepostet habe, aus, leg dich aufs sofa, und lies erstmal in ruhe.

        1. Da muss ich erstmal n kopf für haben um das alles zu lesen bin grad krank da fällt mir das etwa schwer..

          du bist krank, programmierst aber gerade, und lesen fällt dir schwer? wie willst du da programmierfehler entdecken?

          druck dir den link, den ich unten gepostet habe, aus, leg dich aufs sofa, und lies erstmal in ruhe.

          XD lieber versuchen zu programmieren als nur doof rumliegen man kann man ja nicht viel machen wenn man krank ist ausser irgendwas am PC oder primitiv TV gucken was nicht mein ding ist.
          Nur so Tutorials kann ich mir jetzt nicht geben.

          1. XD lieber versuchen zu programmieren als nur doof rumliegen man kann man ja nicht viel machen wenn man krank ist ausser irgendwas am PC oder primitiv TV gucken was nicht mein ding ist.

            OT: ich guck mir gerne dokus auf ZDFinfo, arte etc. an (natur, tiere, geschichte, wissenschaft...), wenn ich krank bin. an die frische luft gehen soll auch helfen, bin ich aber selber auch zu faul für ;-)

            1. XD lieber versuchen zu programmieren als nur doof rumliegen man kann man ja nicht viel machen wenn man krank ist ausser irgendwas am PC oder primitiv TV gucken was nicht mein ding ist.

              OT: ich guck mir gerne dokus auf ZDFinfo, arte etc. an (natur, tiere, geschichte, wissenschaft...), wenn ich krank bin. an die frische luft gehen soll auch helfen, bin ich aber selber auch zu faul für ;-)

              OT Too:
              Jau ich hab bei meinem Receiver auch 2 Listen gepeichert:

              1. Dokus
              2. Schrott

              Aber da laufen auchnicht immer gute Dokus oder die wurden schon zum 1000. mal wiederholt.

  3. Bitte einmal zum Verständnis lesen:
    http://perlgeek.de/de/artikel/charsets-unicode

    Mir hilft es immer, wenn ich genau weiss, was in den Variablen drinsteht, mit denen ich es zu tun habe. "Im Browser sehe ich ein Fragezeichen" ist mir da zu wenig.

    Hiermit siehst du genau, was Sache ist:

    use Devel::Peek; Dump $var;

    Die Daten sollten aus mysql mit utf-8-Flag rauskommen, also dekodiert.
    Beim Rausschreiben (an den Webserver z.B.) musst du die Daten wiederum enkodieren. Z.B. mit Encode::encode_utf8(), oder mit dem setzen von
    binmode STDOUT, ':encoding(UTF-8)';

    1. Bitte einmal zum Verständnis lesen:
      http://perlgeek.de/de/artikel/charsets-unicode

      Mir hilft es immer, wenn ich genau weiss, was in den Variablen drinsteht, mit denen ich es zu tun habe. "Im Browser sehe ich ein Fragezeichen" ist mir da zu wenig.

      Hiermit siehst du genau, was Sache ist:

      use Devel::Peek; Dump $var;

      Die Daten sollten aus mysql mit utf-8-Flag rauskommen, also dekodiert.
      Beim Rausschreiben (an den Webserver z.B.) musst du die Daten wiederum enkodieren. Z.B. mit Encode::encode_utf8(), oder mit dem setzen von
      binmode STDOUT, ':encoding(UTF-8)';

      AHH das wusste ich nicht das ich das noch kodieren muss.
      hab das problem jetzt mit
      binmode(STDOUT, ":utf8");
      gelöst

      Vielen Dank!

      1. AHH das wusste ich nicht das ich das noch kodieren muss.

        daher hilft es ungemein, zum verständnis der ganzen problematik etwas zu lesen =)

        hab das problem jetzt mit
        binmode(STDOUT, ":utf8");
        gelöst

        naja, besser - wie ich schrieb - "encoding(UTF-8)" benutzen.

        perldoc -f binmode:

        To mark FILEHANDLE as UTF-8, use ":utf8" or ":encoding(UTF-8)".  ":utf8" just marks the data as
        UTF-8 without further checking, while ":encoding(UTF-8)" checks the data for actually being
        valid UTF-8.

        1. AHH das wusste ich nicht das ich das noch kodieren muss.

          daher hilft es ungemein, zum verständnis der ganzen problematik etwas zu lesen =)

          hab das problem jetzt mit
          binmode(STDOUT, ":utf8");
          gelöst

          naja, besser - wie ich schrieb - "encoding(UTF-8)" benutzen.

          perldoc -f binmode:

          To mark FILEHANDLE as UTF-8, use ":utf8" or ":encoding(UTF-8)".  ":utf8" just marks the data as
          UTF-8 without further checking, while ":encoding(UTF-8)" checks the data for actually being
          valid UTF-8.

          AH ok Danke :)
          Habs geändert

  4. Also, mit:

    #!/usr/bin/perl use utf8; binmode STDOUT, ":encoding(UTF-8)"; # das scheint hier wichtig zu sein. print "Content-Type: text/html; charset=UTF-8\n\n";

    sehe ich die Umlaute aus meiner Datenbank unter allen Umständen korrekt.

    Jörg Reinholz

    1. Also, mit:

      #!/usr/bin/perl use utf8; binmode STDOUT, ":encoding(UTF-8)"; # das scheint hier wichtig zu sein. print "Content-Type: text/html; charset=UTF-8\n\n";

      sehe ich die Umlaute aus meiner Datenbank unter allen Umständen korrekt.

      schrieb ich ja weiter oben auch, und war laut lxuser auch die lösung.

      das "use utf8" ist hier übrigens unnötig. wird aber oft unwissend verwendet in dem glauben, jedes skript, welches mit unicode arbeitet, braucht "use utf8".
      use utf8 ist nur dann von nutzen (aber auch nicht immer nötig), wenn das skript selbst (also der quelltext) utf8 enthält und beispielsweise direkt im skript notierte variableninhalte automatisch dekodiert sein sollen.

      use utf8; my $text = "ümlaut";

      entspricht dem hier:

      use Encode; my $text = decode_utf8("ümlaut");

      use utf8 dekodiert also sozusagen automatisch im skript vorhandene inhalte.
      inhalte von extern (datenbank, CGI, dateien) müssen weiterhin selbst mittels Encode bearbeitet werden.

      wollte ich nur loswerden aus dem o.g. grund.

      1. schrieb ich ja weiter oben auch, und war laut lxuser auch die lösung.

        Jaja. Ich hatte die Frage eine Weile offen, weil ich Besuch hatte. Inzwischen warst Du halt schneller und ich hatte einen Kaffee.

        Jörg Reinholz