mixmastertobsi: PHP IMAP Umlaute Problem

Hallo,

das Problem mit dem IMAP und Umlaute ist zwar in einigen Foren beschrieben, allerdings konnte ich keine Lösung finden.

Problem ist, dass die Umlaute bei meinem UTF8 Skript falsch dargestellt werden. Ich habe bereits quoted_printable_decode probiert, allerding bringt dies nur bedingt etwas. In dem Fall werden die Umlaute zu "?". Wer hat die Lösung?

ein Paar Beispiel Umlaute

"=E4" = ä

"=FC" = ü

  1. hi,

    ein Paar Beispiel Umlaute

    "=E4" = ä

    "=FC" = ü

    Da macht Dein quoted_printable Mist. Es soll nämlich die Oktetten quoten, fürn ü wären die =C3=BC und fürn ä =C3=A4. Deine Funktion quoted jedoch die Codepoints.

    Was guckst Du

    1. Tach!

      ein Paar Beispiel Umlaute

      "=E4" = ä

      "=FC" = ü

      Da macht Dein quoted_printable Mist. Es soll nämlich die Oktetten quoten, fürn ü wären die =C3=BC und fürn ä =C3=A4. Deine Funktion quoted jedoch die Codepoints.

      Könnte theoretisch sein, wäre aber ziemlich weit davon entfernt, wie die Dinge in der Praxis laufen. PHP arbeitet nicht mit Codepoints, das arbeitet mit Bytes, oder Oktetten, wie du sie zu nennen pflegst. Zu dem wenig wahrscheinlichen Fall, dass er sich eine Quoted-Printable-Funktion selbst geschrieben hat, müsste noch hinzukommen, dass er UTF-8-kodiertes Zeug in Codepoints umrechnet. Wer macht denn sowas und hat dann anscheinend keine Ahnung, wie UTF-8 aussieht?

      dedlfix.

      1. Tach!

        ein Paar Beispiel Umlaute

        "=E4" = ä

        "=FC" = ü

        Da macht Dein quoted_printable Mist. Es soll nämlich die Oktetten quoten, fürn ü wären die =C3=BC und fürn ä =C3=A4. Deine Funktion quoted jedoch die Codepoints.

        Könnte theoretisch sein,

        Praktisch sind in einer ISO-8859-1 Kodierung die Codepoints == Oktettenwertigkeiten.

      2. Wer macht denn sowas

        Eine Frage, die regelmäßig gestellt wird ...

        und hat dann anscheinend keine Ahnung, wie UTF-8 aussieht?

        Naja. Jemand, der mal mehr, mal weniger anerkannte Drittbibliotheken oder Code aus "Kochbüchern" verwendet. Wobei offen bleiben kann ob der Code respektive die Bibliothek oder deren unsachgemäße Verwendung die Ursache des Fehlers ist...

        Den Antworten von Christian Kruse, dedlfix, Rolf b ist inhaltlich nichts mehr hinzuzufügen, die sollten das konkrete Problem lösen. (Alle drei erhalten ein virtuelles +1)

        Nächster Schritt wäre durch ein wenig Text-Voodoo die Kodierung festzustellen und also den Vorgang allgemein gültig zu machen.

        1. Hallo Google weiß alles,

          Nächster Schritt wäre durch ein wenig Text-Voodoo die Kodierung festzustellen und also den Vorgang allgemein gültig zu machen.

          Du meinst mit einem gewissen Restrisiko zu erraten. ;-)

          Bis demnächst
          Matthias

          --
          Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
          1. Du meinst mit einem gewissen Restrisiko zu erraten. ;-)

            Naja. In der Frage, ob die Angabe der Kodierung im Mail wohl korrekt ist (und standardgerecht erfolgt), mag man ein Restrisiko erkennen können - aber das "Text-Voodoo", um die rauszufiltern, halte ich nicht für ein "erraten".

            1. Tach!

              Du meinst mit einem gewissen Restrisiko zu erraten. ;-)

              Naja. In der Frage, ob die Angabe der Kodierung im Mail wohl korrekt ist (und standardgerecht erfolgt), mag man ein Restrisiko erkennen können - aber das "Text-Voodoo", um die rauszufiltern, halte ich nicht für ein "erraten".

              Man kann dein "Text-Voodoo" unterschiedlich interpretieren. Die eine Möglichkeit ist, du meinst die Kodierungsangabe aus den mitgelieferten Metadaten zu ermitteln. Die andere ist, du meinst, die Kodierung anhand der Daten erkennen zu wollen. Letzteres ist prinzipbedingt ein Erraten.

              dedlfix.

              1. Man kann dein "Text-Voodoo" unterschiedlich interpretieren. Die eine Möglichkeit ist, du meinst die Kodierungsangabe aus den mitgelieferten Metadaten zu ermitteln. Die andere ist, du meinst, die Kodierung anhand der Daten erkennen zu wollen. Letzteres ist prinzipbedingt ein Erraten.

                dedlfix.

                Damit hast Du natürlich Recht, das von mir leicht und locker gebrauchte "Text-Voodoo" ist ungenau und lässt damit den falschen Schluss zu. Ich hab es ja auch klargestellt und falls der Martin die Klarstellung nicht oder falsch verstanden haben sollte habe ich jetzt klargestellt, dass ich das völlig kritikfrei klargestellt habe.

                1. Hallo Google weiß alles,

                  und falls der Martin die Klarstellung nicht oder falsch verstanden haben sollte

                  der Matthias 😜

                  Bis demnächst
                  Matthias

                  --
                  Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
                  1. und falls der Martin die Klarstellung nicht oder falsch verstanden haben sollte

                    der Matthias 😜

                    Ups. Google irrt sich! Das wird bei heise der Aufreger der Woche.

                    Danke für Klarstellung.

  2. Tach!

    Problem ist, dass die Umlaute bei meinem UTF8 Skript falsch dargestellt werden. Ich habe bereits quoted_printable_decode probiert, allerding bringt dies nur bedingt etwas. In dem Fall werden die Umlaute zu "?".

    ein Paar Beispiel Umlaute

    "=E4" = ä

    "=FC" = ü

    Das ist kein (quoted-printable) UTF-8, das ist ISO-8859-1 oder -15 oder Windows-1252.

    Wer hat die Lösung?

    Nicht nur sagen, dass man UTF-8 verwendet, sondern die Texte auch wirklich UTF-8-kodiert erzeugen, speichern, was auch immer.

    dedlfix.

    1. Hallo,

      habe nun alles mögliche Probiert zum dekodieren der eMail vom IMAP Postfach. Hat mir ggf noch jemand einen Tipp?

      1. Tach!

        habe nun alles mögliche Probiert zum dekodieren der eMail vom IMAP Postfach. Hat mir ggf noch jemand einen Tipp?

        Ja, mach es richtig. Was du dazu ändern musst? Weiß ich nicht, du schreibst nicht, was du konkret machst, so dass ich nicht erkennen kann, was genau du anders machen musst.

        dedlfix.

        1. Also - das ist der Body aus der original Mail

          Mit freundli= chen Gr=FC=DFen
          

          Probiert habe ich imap_qprint und quoted_printable_decode. Bei beidem bekomme ich folgendes Ergebnis.

          Mit freundlichen Gr��en
          

          Das ist noch die Structur

          stdClass Object ( [type] => 0 [encoding] => 4 [ifsubtype] => 1 [subtype] => HTML [ifdescription] => 0 [ifid] => 0 [lines] => 80 [bytes] => 2781 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [parameters] => Array ( [0] => stdClass Object ( [attribute] => charset [value] => iso-8859-1 ) ) ) 
          

          Das ist noch die Mail im Quelltext - von Outlook versandt

          <html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
          osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
          xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
          //www.w3.org/TR/REC-html40">
          <head>
          <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
          1">
          <meta name=3D"Generator" content=3D"Microsoft Word 15 (filtered medium)">
          <style><!--
          /* Font Definitions */
          @font-face
          	{font-family:"Cambria Math";
          	panose-1:2 4 5 3 5 4 6 3 2 4;}
          @font-face
          	{font-family:Calibri;
          	panose-1:2 15 5 2 2 2 4 3 2 4;}
          /* Style Definitions */
          p.MsoNormal, li.MsoNormal, div.MsoNormal
          	{margin:0cm;
          	margin-bottom:.0001pt;
          	font-size:11.0pt;
          	font-family:"Calibri",sans-serif;
          	mso-fareast-language:EN-US;}
          a:link, span.MsoHyperlink
          	{mso-style-priority:99;
          	color:#0563C1;
          	text-decoration:underline;}
          a:visited, span.MsoHyperlinkFollowed
          	{mso-style-priority:99;
          	color:#954F72;
          	text-decoration:underline;}
          span.E-MailFormatvorlage17
          	{mso-style-type:personal-compose;
          	font-family:"Calibri",sans-serif;
          	color:windowtext;}
          .MsoChpDefault
          	{mso-style-type:export-only;
          	mso-fareast-language:EN-US;}
          @page WordSection1
          	{size:612.0pt 792.0pt;
          	margin:70.85pt 70.85pt 2.0cm 70.85pt;}
          div.WordSection1
          	{page:WordSection1;}
          --></style><!--[if gte mso 9]><xml>
          <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
          </xml><![endif]--><!--[if gte mso 9]><xml>
          <o:shapelayout v:ext=3D"edit">
          <o:idmap v:ext=3D"edit" data=3D"1" />
          </o:shapelayout></xml><![endif]-->
          </head>
          <body lang=3D"DE" link=3D"#0563C1" vlink=3D"#954F72">
          <div class=3D"WordSection1">
          <p class=3D"MsoNormal">Mit freundlichen Gr=FC=DFen<o:p></o:p></p>
          </div>
          </body>
          </html>
          
          1. Tach!

            Also - das ist der Body aus der original Mail

            Mit freundli= chen Gr=FC=DFen
            

            Das ist kein quoted printable UTF-8.

            Das ist

            stdClass Object ( [attribute] => charset [value] => iso-8859-1 )
            

            Das ist noch die Mail im Quelltext - von Outlook versandt

            <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
            1">
            

            dedlfix.

            1. Und wie decodiere ich dann - Deiner Meinung nach?

              mb_convert_encoding habe ich auch bereits ausprobiert.

              mb_convert_encoding($body, "UTF-8", "iso-8859-1");
              
              1. Hallo mixmastertobsi,

                Und wie decodiere ich dann - Deiner Meinung nach?

                mb_convert_encoding habe ich auch bereits ausprobiert.

                mb_convert_encoding($body, "UTF-8", "iso-8859-1");
                

                Emails haben mehrere Ebenen an Kodierungsverfahren. Die erste Ebene ist das Charset, damit bezeichnet man die Kodierung, mit der die einzelnen Zeichen kodiert werden. Das kann UTF-8 sein, das kann ISO-8859-1 sein, aber es kann eben auch Big5 sein. In deinem Fall scheint das ISO-8859-1, ISO-8859-15 oder Windows-1252 sein - die kann man schwer auseinander halten, denn sie sind sich in vielen Punkten sehr ähnlich. Welches Encoding das genau ist, steht aber in deiner Mail. In deren Headern steht sowas wie Content-Type: text/plain; charset=ISO-8859-1 oder ähnliches.

                Die nächste Ebene ist das Transport Encoding. Das ist häufig Base64 oder Quoted Printable, in deinem Fall ist das Quoted Printable. Das wird über den Text nochmal drüber laufen gelassen, um zu verhindern, dass Zeichen ausserhalb von ASCII übermittelt werden: bei Emails ist nach wie vor nicht sicher gestellt, dass alles überhalb der ASCII-Range auch tatsächlich fehlerfrei übermittelt werden kann.

                Um also den Text korrekt darzustellen musst du zuerst den Text von Quoted Printable in die 8-Bit-Kodierung übertragen, das macht quoted_printable_decode. Danach musst du den Text in den Zeichensatz übertragen, in dem deine Website dargestellt wird. Das machst du mit deinem mb_convert_encoding.

                Welches der Quellzeichensatz ist und ob Quoted Printable verwendet wurde liest du am besten aus den Header-Informationen.

                LG,
                CK

              2. Tach!

                Und wie decodiere ich dann - Deiner Meinung nach?

                Erst muss das Quoted Printable weg. Dann hast du einen String in ISO-8859-1-Kodierung. Den kannst du dann umkodieren nach UTF-8.

                Die Email ist zweifach kodiert (abgesehen vom HTML-Code). Zuerst wird der Text in eine physikalische Kodierung gebracht. Das heißt, die Zeichen werden entsprechend der Kodierungsvorschrift als ein oder mehrere Bytes geschrieben. Nun gibt es das historisch begründete Problem, dass Bytes oberhalb von 0x7E und unterhalb von 0x32 nicht verwendet werden. Diese werden nun mit Quoted Printable in eine 7-Bit-kompatible Form gebracht. Wenn du nun den originalen Text wieder haben möchtest, musst du die ganze Chose rückwärts aufdrieseln. Quoted Pritable interessiert sich nicht für Zeichen oder Bytekombinationen, die irgendwelche Zeichen darstellen, es behandelt jedes Byte einzeln und rückwärts entsteht dieselbe Bytefolge wie vorwärts eingekippt wurde. Davor und danach hast du also dieselbe Zeichen-Kodierung. Es findet keine automatische Umkodierung nach UTF-8 oder sonstwohin statt.

                dedlfix.

              3. Also prinzipiell sollte mb_convert_encoding funktionieren; zumindest funktionierte es gerade bei mir (in http://sandbox.onlinephpfunctions.com/)

                $test = "T=E4st f=FCr Dich";
                $dec = quoted_printable_decode($test);
                $utf = mb_convert_encoding($dec, "UTF-8", "iso-8859-1");
                echo $dec;
                echo $utf;
                

                Ergebnis war

                T�st f�r DichTäst für Dich
                

                Voraussetzung sollte sein:

                • Du hast im <head> deiner Seite stehen, dass Dein Content-Type utf-8 ist
                • Dein PHP hat Multibyte Support vollständig aktiviert. Ich würde zwar erwarten, dass bei fehlender Aktivierung die mb_ Funktionen gänzlich streiken, aber mir fehlt an dieser Stelle die Erfahrung, was da alles wie schiefgehen kann.

                Rolf

      2. Hallo,

        habe nun alles mögliche Probiert zum dekodieren der eMail vom IMAP Postfach. Hat mir ggf noch jemand einen Tipp?

        Guck in den Mail-Header, da steht i.d.R. die Kodierung drin. D.h., da hat sie gefälligst drin zu stehen ;)