Ankündigung

Einklappen
Keine Ankündigung bisher.

Nochmal UTF-8

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Nochmal UTF-8

    Hi

    lese per Excel Reader eine Excel 2000 Datei ein und speichere die Daten in MySQL (UTF-.

    Den Reader stelle ich ein per

    PHP-Code:
    $xl->SetOutputEncoding('UTF-8'); 
    Testweise habe ich polnische und russische Zeichen sowie deutsche Umlaute etc. eingesetzt.

    Das Skript speichert die polnischen und russischen Zeichen so wie erwartet. Diese Zeichen lassen sich auch in anderen Bereichen der gesamten Anwendung wieder richtig ausgeben.

    Worte mit deutschen Umlauten werden jedoch dort abgeschnitten, wo der erste Umlaut beginnt. Statt Gebühr wird dann nur Geb gespeichert.

    Ich habe die Excel-Reader Klasse durchforstet und gesehen, dass dort per iconv von der Excelkodierung UTF-16LE zu UTF-8 (siehe oben OutputEncoding) gewandelt wird.

    Hat jemand eine Ahnung, warum ausgerechnet deutsche Umlaute nicht gespeichert werden?
    Es ist schon alles gesagt. Nur noch nicht von allen.


  • #2
    welches Script?

    Kommentar


    • #3
      Übergibst du die Zeichen auch per UTF-8? Klappt es, wenn dein String mit einem Multibytezeichen beginnt ("Österreich")? Evtl. klappt dann die automatische Zeichensatzerkennung nicht.
      "Mein Name ist Lohse, ich kaufe hier ein."

      Kommentar


      • #4
        Zitat von Chriz Beitrag anzeigen
        Übergibst du die Zeichen auch per UTF-8? Klappt es, wenn dein String mit einem Multibytezeichen beginnt ("Österreich")? Evtl. klappt dann die automatische Zeichensatzerkennung nicht.
        Ja, siehe oben. Klappt ja auch bei polnisch, kyrillisch.
        Bei Österreich bleibt das DB-Feld leer.
        Automatische Zeichensatzerkennung: Es ist ja so, die Quelle ist eine Excel-Datei, die in UTF-16LE vorliegt. Der Excel-Reader konvertiert in die gewünschte Zeichenkodierung per iconv, was ja auch bei allem möglichen Kram außer deutschen Umlauten und ß funktioniert.

        Irgendwas stimmt da nicht mit iconv, vermute ich. Habe mich inzwischen zu Tode gegoogelt. Es gibt wohl andere mit ähnlichen Problemen aber auffällig wenig Lösungsansätze.
        Es ist schon alles gesagt. Nur noch nicht von allen.

        Kommentar


        • #5
          Wie genau sieht der iconv-Aufruf aus?

          Kommentar


          • #6
            Ich hatte ein ähnliches Problem beim Import einer alten sehr großen DBF aus DOS Zeiten, in der jede Menge deutsche Umlaute enthalten waren.
            Ich konnte sie nicht in Excel öffnen und als SQL exportieren, da sie 140.000 Einträge hatte

            Die Lösung ist NAVICAT, gibt es auch als Lite Version (Freeware).
            Der Import mit der Kodierung "852 (OEM - Latin II)" oder "850 (OEM - Multilingual Latin I)" brachte dann das gewünschte Ergebnis.

            Alle Umlaute und Sonderzeichen wurden fehlerfrei importiert.

            Kommentar


            • #7
              Zitat von ChrisB Beitrag anzeigen
              Wie genau sieht der iconv-Aufruf aus?
              Habe es gerade mal aus dem Excel Reader kopiert

              1.

              PHP-Code:
              function setOutputEncoding($encoding)
                  {
                      
              $this->_defaultEncoding $encoding;
                  } 
              Diese Methode nutze ich ja in meinem Script. => UTF-8

              2.
              PHP-Code:
              function setUTFEncoder($encoder 'iconv')
                  {
                      
              $this->_encoderFunction '';
                      if (
              $encoder == 'iconv') {
                          
              $this->_encoderFunction function_exists('iconv') ? 'iconv' '';
                      } elseif (
              $encoder == 'mb') {
                          
              $this->_encoderFunction function_exists('mb_convert_encoding') ?
                                                    
              'mb_convert_encoding' :
                                                    
              '';
                      }
                  } 
              Den Encoder lasse ich auf dem Defaultwert iconv stehen

              3. Der Kern der Sache
              PHP-Code:
              function _encodeUTF16($string)
                  {
                      
              $result $string;
                      if (
              $this->_defaultEncoding){
                          switch (
              $this->_encoderFunction){
                              case 
              'iconv' :     $result iconv('UTF-16LE'$this->_defaultEncoding$string);
                                              break;
                              case 
              'mb_convert_encoding' :     $result mb_convert_encoding($string$this->_defaultEncoding'UTF-16LE' );
                                              break;
                          }
                      }
                      return 
              $result;
                  } 
              Es ist schon alles gesagt. Nur noch nicht von allen.

              Kommentar


              • #8
                PHP-Code:
                $testwert 'Oberösterreich';
                $test1 urlencode(iconv('UTF-8''UTF-16LE'$testwert));
                $test2 iconv('UTF-16LE''UTF-8'urldecode($test1));
                echo 
                $test2;
                var_dump($testwert === $test2); 
                Dieses Testscript ist in UTF-8 gespeichert, und wird auch in UTF-8 ausgeliefert.
                (Die URL-Kodierung habe ich eingebaut, um Testausgaben machen und per Copy&Paste übernehmen zu können, die in einer anderen Kodierung als mein Script vorliegen, hier also UTF-16LE.)

                Das gibt mir wie erwartet "Oberösterreich" und "bool(true)" aus - also hat iconv hier wohl nichts falsch gemacht.


                Dass deine Daten überhaupt nicht in UTF-16LE vorliegen, scheint mir wahrscheinlicher; siehe auch Antwort von Registrierer.

                Kommentar


                • #9
                  Also ich habe jetzt einen Befund und einen Work_Around:

                  Habe kurz vor dem INSERT in die DB per mb_detect_encoding das Encoding des jeweiligen Wertes aus der Exceltabellenspalte ausgegeben. Erstaunlicherweise sieht das so aus.
                  Code:
                  ISO-8859-1<br>UTF-8<br>UTF-8<br>UTF-8<br>UTF-8<br>UTF-8<br>UTF-8<br>
                  D.h. der erste (und einzige) Eintrag mit den Umlauten wird trotz iconv als ISO-8859-1 erkannt. Hm, habe es jetzt so gelöst:
                  PHP-Code:
                  $current_encoding mb_detect_encoding($descr_short,'UTF-8, ISO-8859-1');
                  if (
                  $current_encoding != "UTF-8") {
                      
                  $descr_short iconv($current_encoding,'UTF-8',$descr_short);

                  Also quasi mit der Brechstange nochmal iconv drüberlaufen lassen. Hey, das klappt.
                  Es ist schon alles gesagt. Nur noch nicht von allen.

                  Kommentar


                  • #10
                    Dass deine Daten überhaupt nicht in UTF-16LE vorliegen, scheint mir wahrscheinlicher; siehe auch Antwort von Registrierer.
                    Das kann ich mir eigentlich nur schwer vorstellen. Ich nutze Microsoft Excel, um die Ausgangstabelle zu erstellen. Die ist nun mal in UTF-16LE. Mag sein, dass da ein Bug drin hängt, glaube ich aber erst mal nicht. Der Konvertierungsprozess des Excel-Readers funktioniert für alle Werte nur nicht, wenn der ein Deutscher Umlaut vorliegt. Wie gezeigt. Erklären kann ich mir das nicht. Andere, die ähnliche Probleme hatten beschrieben das auch u. a. im Zs.hang mit Importen. Vielleicht liegt da das Problem irgendwo.
                    Es ist schon alles gesagt. Nur noch nicht von allen.

                    Kommentar


                    • #11
                      Zitat von drsoong Beitrag anzeigen
                      D.h. der erste (und einzige) Eintrag mit den Umlauten wird trotz iconv als ISO-8859-1 erkannt.
                      Es wird immer die erste passende Kodierung verwendet. Manchmal kann der gleiche Text ja auch in mehreren Zeichensätzen die selbe binäre Darstellung besitzen. Das ist ja eben auch ein Vorteil von UTF-8.
                      "Mein Name ist Lohse, ich kaufe hier ein."

                      Kommentar


                      • #12
                        Zitat von Chriz Beitrag anzeigen
                        Es wird immer die erste passende Kodierung verwendet. Manchmal kann der gleiche Text ja auch in mehreren Zeichensätzen die selbe binäre Darstellung besitzen. Das ist ja eben auch ein Vorteil von UTF-8.
                        Hä. Also mal Schritt für Schritt.

                        Du schreibst Dir eine 7-Zeilen-Testtabelle in MS-Excel 2000.
                        Du lädst die per Uploadscript in die DB.
                        Zum Einlesen der Exceltabelle nutzt Du Spreadsheet Excel Reader
                        (Kriegst Du bei SourceForge.net)
                        Excel Reader nutzt iconv um die Werte Deiner Tabelle in das von Dir vorgegebene Encoding zu wandeln. Dass die Ausgangskodierung UTF-16LE ist, ist klar da MS-Excel. Also
                        PHP-Code:
                        iconv('UTF-16LE','UTF-8',$string); 
                        Wenn da jetzt bei den Umlauten per mb_detect_encoding ISO-8859-1 rauskommt, heißt das entweder, dass MS-Excel Umlaute nicht in UTF-16LE kodiert oder das iconv irgendwo defekt ist.

                        Was meinst Du jetzt mit
                        ...die erste passende Kodierung ...
                        Es ist schon alles gesagt. Nur noch nicht von allen.

                        Kommentar


                        • #13
                          PHP-Code:
                          <?php
                          echo mb_detect_encoding("Auto""ISO-8859-1,UTF-8"); // ISO-8859-1
                          echo mb_detect_encoding("Auto""UTF-8,ISO-8859-1"); // UTF-8
                          ?>
                          mb_detect_encoding() ist ziemlich oft fürn Arsch, aber das meinte ich damit garnicht. Ich meinte damit, dass es relevant ist, in welcher Reihenfolge du den 2. Parameter übergibst. Deshalb kam evtl. ISO raus und nicht wie erwartet UTF-8, obwohl es gleichsam UTF-8 gewesen sein kann.
                          "Mein Name ist Lohse, ich kaufe hier ein."

                          Kommentar


                          • #14
                            Zitat von drsoong Beitrag anzeigen
                            Also
                            PHP-Code:
                            iconv('UTF-16LE','UTF-8',$string); 
                            Wenn da jetzt bei den Umlauten per mb_detect_encoding ISO-8859-1 rauskommt, heißt das entweder, dass MS-Excel Umlaute nicht in UTF-16LE kodiert oder das iconv irgendwo defekt ist.
                            Nein, das heißt erst mal nur das, was Chriz gerade schon versucht hat zu erklären: Dass mb_detect_encoding die Kodierung nicht bestimmen kann, weil das in vielen Fällen gar nicht zweifelsfrei geht.
                            Die Funktion kann nur raten - und gibt sich dabei offenbar mit dem ersten Treffer zufrieden.


                            Wenn du absolut hundertprozentig sicher bist, dass Excel dir die Daten in UTF-16LE kodiert liefert - dann bräuchte es gar kein mb_detect_encoding mehr, dann würde das umkodieren von dieser Kodierung in UTF-8 ausreichen.

                            Kommentar


                            • #15
                              mb_detect_encoding() ist ziemlich oft fürn Arsch,
                              Verblüffend. Hatte mb_detect_encoding erst heute notgedrungenerweise kennengelernt. O.K., das verstehe ich jetzt und das von ChrizB, denke ich, auch. Jetzt muß ich nochmal prüfen, warum mein Workaround funktioniert. Der wandelt ja in UTF-8, wenn UTF-8 per mb_detect_encoding nicht erkannt wird. Sollte jetzt dennoch UTF-8 vorliegen, würde doch UTF-8 in UTF-8 kodiert, was doch eigentlich nen ziemlichen Zeichensalat ergeben müßte. Werde jetzt erst mal mein kringeligen Augen entspannen. Alles weitere von meiner Seite dann morgen wieder. Danke an Euch.
                              Es ist schon alles gesagt. Nur noch nicht von allen.

                              Kommentar

                              Lädt...
                              X