Tom: eMail senden mit mail(), Codierungsprobleme

Hello,

lang ist's her, dass ich selber was dazu verfasst habe und es hat damals zuverlässig funktioniert. Leider ist mein Mail-Modul verschollen. In meinen 1000 Postings hier zum Thema habe ich die Gedanken auch noch nicht alle wiederfinden können.

Jedenfalls habe ich mich jetzt im Dschungel von Zeichencodierung, Transfer-Encoding, Header-Zeilen, was macht der Mailclient "einfach so?" usw. verlaufen.

Stand der Tests ist:

  
  
<?php   mailtest.php ### Versand von Mail mit Attachment ### utf-8 ### ÄÖÜäöü  
  
$filename = __FILE__;  
$content  = chunk_split(base64_encode(file_get_contents($filename)), 76, PHP_EOL);  
#$content = base64_encode(file_get_contents($filename), 76, PHP_EOL);  
  
  
$mailto 	= 'tschmieder@online.de';  
$subject 	= 'Mail-Test (8) ASCII mit ÄÖÜäöü and boundary';  
$message	= 'Hier kommt der öffentliche Text mit dämlichen Übelkeiten und Ödemen';  
$header	    = "from: info@bikers-lodge.com\n";  
$time       = time();  
$boundary   = "----=_TSMail-Next-Part-$time";  
  
$header    .= "Content-Type: multipart/mixed;\n";  
$header    .= "  boundary=\"$boundary\"\n";  
  
$message   .= "\n\n--$boundary\n";  
$message   .= "Content-Type: text/plain;\n";  
$message   .= "  charset=iso-8859-1\n";  
$message   .= "Content-Transfer-Encoding: 8bit\n\n";  
$message   .= "Test-Mail mit Anhang, bitte den Quelltext der Mail kopieren und nachher mitbringen\n\n";  
  
$message   .= "\n--$boundary\n";  
$message   .= "Content-Type: text/plain;\n";  
$message   .= "  name=\"attachment.txt\"\n";  
$message   .= "Content-Transfer-Encoding: base64\n";  
$message   .= "Content-Disposition: attachment;\n";  
$message   .= '  filename="' . basename($filename) . "\"\n\n";  
$message   .= $content . PHP_EOL;  
$message   .= "\n--$boundary--\n";  
  
$sent = mail($mailto, $subject, $message, $header);  
  
  
  
echo "\r\n<pre>\r\n";  
  
echo ($sent)?date('Y-m-d H:i:s') . ": Mail wurde versandt\r\n":"Mail wurde nicht versandt\r\n";  
  
echo "</pre>\r\n";  
  
?>  
  

Das funktioniert auch soweit, wenn der Client ein Thunderbird ist. Andere konnte ich leider nicht testen im Moment.

Wenn ich den vermeintlichen Quelltext der empfangenen Mail dann speichere und ihn anschließend mit notepad++ in der Codierung "utf-8 ohne BOM" anschaue, wird auch alles richtig angezeigt.

Alles, was der User sehen muss, zeigt der Thunderbird auch richtig an.

Wenn ich mir den Quelltext aber nun anzeigen lassen mit "Thunderbird/Quelltext anzeigen", dann bekomme ich schon wieder Bauchschmerzen:

Received: by h2222671.stratoserver.net (Postfix, from userid 33)
id C4D8B6CA097; Tue,  4 Mar 2014 14:10:03 +0100 (CET)
To: tschmieder@online.de
Subject: Mail-Test (8) ASCII mit ÄÖÜäöü and boundary
X-PHP-Originating-Script: 0:mailtest.php
from: info@bikers-lodge.com
Content-Type: multipart/mixed;
  boundary="----=_TSMail-Next-Part-1393938603"
Message-Id: 20140304131003.C4D8B6CA097@h2222671.stratoserver.net
Date: Tue,  4 Mar 2014 14:10:03 +0100 (CET)
Envelope-To: tschmieder@online.de
X-UI-Filterresults: notjunk:1;V01:K0:6ZHqduRylEA=:kdADYP2ysE4jZDDDsngeb5qM19
 higEP6GOVerbd3h59qnGdV5T75uNyUQvTAx5E866TZXIRtUg5ESlP7OUA5VDrQe+O0Kf5Y7DV
 mPU66X7FAN26W787qvhhsVmiGiln8zcnOaHY6i/tualP3aVxOkPinUDWOGY5DvjDduPMRYZkX
 aGgtFziOmbU044aL31xsjJxY8VSCH2tQOaLpRVqwla5g4pbCRhzkAtYOMjOdrTxDuoBgoDmYs
 Zz8hoAOIwoZFino4BuUuVekmtd1ZuI5Ch16hCRbuGYJESK5oSwhazIfzswjjJe75sPgDknz9x
 6QiAH5q9V8lDY8n/ygddW9be5kdK4nsq0x/AzB36S3B/1ZGVKnsOs5vcddTOlVUp6OfLsv3OV
 PZyjTnAzClasZagcVsREKfm6OR59G3cyWzcZ4BT1UGI9mInoebVDJEdBpJ6pZuBzddEEZlDwP
 wzBBpfmyQl8NPt4nXgWNBGtJaR7H5Bi3ix/cS4VflC9XdtBrzswray21ahQiunMQyNwpiN1AC
 Il16YMmc6sbiHYJa5EfUWZ82+DpUhBP/2mQV5mi+T8v/W+oKh6Vsx+Vt4lVYWjGL2L1GRk3FW
 IR/mWaHsduJhTpa0n0/4elb9z4e4XoZRA5TxNLjFD5W7FGB+zkSLarAgi14JKpf3Vh//ydCHp
 CoS1PGyg6V0TCLdbdel6Ec16P8TKTjMwAoLdf1alXtyI5S1lWAXumDmTHudSHNWfgzdi0eeeP
 Bdm15PgitVaYLeLnBel6+yvaE/aLmcX3nk5aJgHpitf4/T5tTYkwBOtBDUy5iEUA3BB8o68+d
 DTNGEGXua1Li8ojJ3QyKuCYGMk8XzMBrPHiaOkwCQW0lJ9kdjT8a4PCOF0AQxYxcsu4tDmHgf
 d64k9HJhgZPK/oN9ZLWiqw07ZUZ5gFdnykx4CM+VsxYwGeVsiZgExyo+fhHRvUdwijATBMRK3
 AoxDKsrdzxWk7qkNZwEBtNDd4j+mY4ysCMxkNBqDxP3oFMyx2pkwRL24ZFxCvomKU6tmtM7VS
 0YN81MHO0fp/KHRc65zDTAA/Iplbu2YjX/DyXUoh8chJtrfu1wo4X1UlPnUC/OBZOS/Ofj3mk
 M4Z0Y3bTmR6EBzYpOXp96abcknYuMjQn+OHosRxdivlqZrwzejeHCZ6IAo5YiEk0lcf5rnyVz
 BK+S8jTXi6KIW2ltXjGDXofhOuJ2x1dv/B5gCBrUD6MGFRV5aW78hST1vyvHyN61ETUdlumpm
 gELn96zooaruMBGPHn7yl1ajFDP/YzUFCzQ9/Dw5LtxEdhj4c2DHZ7e0=
Old-X-EsetId: 8DD79423D8FC0F37DC92C5
Old-X-EsetId: 8DD79423D8FC0F37DC92C5
Old-X-EsetId: 8DD79423D8FC0F37DC92C5
X-EsetId: 8DD79423D8FC0F37DC92C5

Hier kommt der öffentliche Text mit dämlichen Übelkeiten und Ödemen

------=_TSMail-Next-Part-1393938603
Content-Type: text/plain;
  charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Das ist die Ansicht in iso-8859-1-Codierung. Die wäre aber für Mails eigentlich naheliegender, als utf-8, da mMn mailheader immer noch ausschließlich ASCII enthalten dürfen... Oder?

Und woher hat der Mail-Server "Content-Transfer-Encoding: quoted-printable". Hab ich nirgends so angegeben. Ganz im Gegenteil, ich schrieb

Content-Transfer-Encoding: 8bit\n\n";

Das hatte ich mir aus einer alten Testmail von OE so rausgepult.

Ich habe einfach im Moment den Überblick (und das Gedächtnis dafür) verloren, wer an welcher Stelle was verkurbelt, was ich nicht sofort sehe. Da ich keinen näheren Zugriff auf die Mailserver habe (weder Sender, noch Empfänger), kann ich leider auch nicht generisch (mit HEX-Editor) ind die gehandetlen Files reinschauen...

Wer bringt mich mal wieder auf die Spur?

Liebe Grüße aus dem schönen Oberharz

Tom vom Berg

--
 ☻_
/▌
/ \ Nur selber lernen macht schlau
http://bikers-lodge.com
  1. Hi,

    Jedenfalls habe ich mich jetzt im Dschungel von Zeichencodierung, Transfer-Encoding, Header-Zeilen, was macht der Mailclient "einfach so?" usw. verlaufen.

    PHPMailer, Swift Mailer o.ä. – und *done*.

    Es lohnt den Aufwand einfach nicht, sich damit heutzutage selber noch auseinanderzusetzen – nur um dann am Ende vielleicht doch wieder irgendwas nicht bedacht zu haben, was deine Testfälle nicht abgedeckt haben.

    MfG ChrisB

    --
    Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
    1. Hello,

      Jedenfalls habe ich mich jetzt im Dschungel von Zeichencodierung, Transfer-Encoding, Header-Zeilen, was macht der Mailclient "einfach so?" usw. verlaufen.

      PHPMailer, Swift Mailer o.ä. – und *done*.

      Es lohnt den Aufwand einfach nicht, sich damit heutzutage selber noch auseinanderzusetzen – nur um dann am Ende vielleicht doch wieder irgendwas nicht bedacht zu haben, was deine Testfälle nicht abgedeckt haben.

      Das ist nett von Dir, dass Du mir Arbeit ersparen willst.
      An die Verwendung einer fertigen Klasse habe ich selbstverständlich auch schon gedacht, aber...

      mir geht es hier nochmal um das Verstehen. Bezahlt werde ich sowieso nicht anständig für die Hilfeleistung und daher möchte ich zumindest meine verschütteten Kenntnisse zum Thema wieder ausgraben.

      Aber ich werde mal versuchen, in die genannten Fertiglösungen hineinzuschauen. Ist ja auch schon mal ein Ansatz.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bikers-lodge.com
      1. Hi,

        mir geht es hier nochmal um das Verstehen.

        Also wenn du im Subject Zeichen ausßerhalb von ASCII verwenden willst, dann solltest du es passend kodieren, das ist korrekt – alle Angaben zur Inhalts-Kodierung wie Content-Transfer-Encoding und Charset beziehen sich erst m.W. auf den Body-Part.

        $subject = '=?UTF-8?B?'.base64_encode($subject).'?=';
        wäre eine Variante, die für ein UTF-8 kodiertes Subject funktionieren sollte.

        Für ein paar mehr Details dazu schau mal hier: http://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/

        MfG ChrisB

        --
        Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
        1. hi,

          Ich mach mich bestimmt unbeliebt, aber:

            
          <?php ob_start()?>  
          
          

          ?UTF-8?B?<?php echo base64_encode($subject)?> ?=;
          und so weiter <?php echo $mitPHPVars?> und noch mehr

          <?php $subject = "ob_get_clean()"?>  
          
          

          mfg

          tami

          1. Hello tami,

            Ich mach mich bestimmt unbeliebt, [...]

            Nee!.

            Aber wofür benötigst Du den Output-Buffer?

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bikers-lodge.com
            1. hi,

              Hello tami,

              Ich mach mich bestimmt unbeliebt, [...]

              Nee!.

              Aber wofür benötigst Du den Output-Buffer?

              Na, damit ich den Text als Text schreiben kann und alles besser lesbar wird. mit .= " ... " und echo "<pre> ..." betreibt man aus meiner Sicht sinnfreie Obfuscation, da Du immer aufpassen musst, dass Du mit der Escaperei keine Fehler baust und überhaupt den eigentlichen Text, auf den es ankommt, unlesbarer machst. Und reine Textausgaben kannst Du dann nur über den Output-Buffer einfangen ...; in Deinem Fall bei den Headern insbesonders.

              mfg

              tami

              1. Lieber tami,

                was bitte spricht denn dagegen, dass Du Dir alle HTML-Ausgaben in einer Variable sammelst, um am Ende diese mit einem einzigen echo oder print an den Browser zu senden?

                Na, damit ich den Text als Text schreiben kann und alles besser lesbar wird. mit .= " ... " und echo "<pre> ..." betreibt man aus meiner Sicht sinnfreie Obfuscation, da Du immer aufpassen musst, dass Du mit der Escaperei keine Fehler baust und überhaupt den eigentlichen Text, auf den es ankommt, unlesbarer machst. Und reine Textausgaben kannst Du dann nur über den Output-Buffer einfangen ...; in Deinem Fall bei den Headern insbesonders.

                Ich bin mir jetzt ziemlich sicher, dass ich nicht verstanden habe, was Du eigentlich sagen willst. "Reine Textausgaben" willst Du in welchem Kontext wohin senden? Welche Debug-Möglichkeiten könntest Du benötigen, die sich mit einer reinen Textdatei nicht lösen ließen?

                Da ich mir angewöhnt habe, meine neuen Projekte grundsätzlich lokalisierbar zu gestalten, verwende ich Textbausteine, die es grundsätzlich in de und en gibt, und die in einer JSON-Datei vorgehalten werden:

                {  
                    "apply-button-text" : {  
                        "de" : "anwenden",  
                        "en" : "apply"  
                    },  
                    "guestbook-title" : {  
                        "de" : "Gästebuch",  
                        "en" : "Guestbook"  
                    }  
                }
                

                Solche Dateien sind in UTF-8 kodiert als "i18n.json"-Datei in meinem Projekt abgelegt und werden dann mittels einer "translate" genannten Funktion an Ort und Stelle verwendet. Wenn man es sich noch schöner machen will, dann kann man diese Textbausteine auch gleich in Templates nutzen:

                <html>  
                    <head>  
                        <title>{#guestbook-title}</title>  
                    </head>  
                    <body>  
                        <h1>{#guestbook-title}</h1>  
                        <p>  
                            <input name="apply" type="submit" value="{#apply-button-text}" />  
                        </p>  
                    </body>  
                </html>
                

                Mit einer schönen Ersetzungsfunktion lassen sich so die textuellen Bestandteile schön von der Programmlogik trennen und benötigen kein Geschwurbel mit <?= ...?> mehr. Auch der OutputBuffer wird so nicht mehr benötigt, da alles HTML in einer Variable vorgehalten wird, bis es an den Browser gesandt wird.

                Wozu will man seine Templates mit PHP-Code zumüllen??

                Liebe Grüße,

                Felix Riesterer.

                --
                ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
                1. hi,

                  Wozu will man seine Templates mit PHP-Code zumüllen??

                  Aber hier bei der Mailerei und dem Header gehts doch nicht mit JSON, oder?
                  Es macht keinen Sinn, 10 Zeilen mit .= " ... einzufangen. In meinen Augen. Da hat jeder so seine Vorlieben ;-).

                  mfg

                  tami

          2. hi,

            Ich mach mich bestimmt unbeliebt,

            endlich mal einer, der sich Gedanken macht um eine sinnvolle Verwendung des OutputBuffers.

            aber:

            Warum nicht gleich ein Template für die Erstellung von Maildateien? Damit ergibt sich ein schön überschaubarer Code, Du siehst bereits im Template, wie die Maildatei aufgebaut ist und etwaige Fehler sind schnell eingekreist.

            Nein, Du machst Dich hier nicht unbeliebt. Es gibt immer noch ein paar Wenige, mit denen Du Deine Begeisterung fürs Programmieren (UND eigene Ideen) teilen kannst.

            ?UTF-8?B?<?php echo base64_encode($subject)?> ?=;

            Auch ne Variante mit dem Vorteil, dass das Encoding mit dieser Funktion grundsätzlich unabhängig von jedwelchen Zeichenkodierungen ist und fernab von den seit Bestehen der mb_Funktionen ausgehenden Unklarheiten (diesbezüglich spricht das Forum Bände).

            Genauso wie Base64 ist Quoted-Printable auch eine reine Byte-Geschichte. Für Subject und Texte in Mails ist QP zu bevorzugen, da es diese Empfehlung schon seit Jahrzehnten gibt, ists mir auch einwenig unbegreiflich, wie sich PHP so stark machen konnte, ohne eine QP-Implementierung als Built-In ;)

            Es spricht jedoch absolut nichts dagegen, QP RFC-gerecht mit einer eigenen Funktion umzusetzen. Bitteschön dran denken: QP quotet nicht Zeichen sondern Bytes.

            Schönes Wochenende,
            Horst

    2. Lieber ChrisB,

      PHPMailer, Swift Mailer o.ä. – und *done*.

      das würde ich liebend gerne tun... nur sind diese Bibliotheken solche "Monster", dass ich dafür gleich eine ganze Verzeichnisstruktur in mein Projekt übernehmen muss, anstatt eine einzelne PHP-Datei (welche ich mir auch noch beliebig benennen könnte).

      Warum kriegt man solche "libs" eigentlich nicht "single-file"?

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. hi,

        Lieber ChrisB,

        PHPMailer, Swift Mailer o.ä. – und *done*.

        das würde ich liebend gerne tun... nur sind diese Bibliotheken solche "Monster", dass ich dafür gleich eine ganze Verzeichnisstruktur in mein Projekt übernehmen muss, anstatt eine einzelne PHP-Datei (welche ich mir auch noch beliebig benennen könnte).

        Warum kriegt man solche "libs" eigentlich nicht "single-file"?

        Beim Zend-Framework hat jede Klasse erstmal einen File. Und wenn da noch mehrere Klassen zum assistieren benötigt werden, liegen die alle in einen gleichnamigen Ordner. Ich meine, du brauchst beim Zend-Framework im wesentlichen die Zend-Klasse und dann alles, was im Mail-Ordner drinne ist. Das war/ist(?) bei PEAR auch so (gewesen).

        Es steht Dir doch aber frei, Dir das zusammenzukopieren in ein File. Soooo viele Abhängigkeiten sollten das mWn. nich sein.

        mfg

        tami

        1. Lieber tami,

          Es steht Dir doch aber frei, Dir das zusammenzukopieren in ein File. Soooo viele Abhängigkeiten sollten das mWn. nich sein.

          bei JS-Bibliotheken bekommt man ja auch minifizierten Code - zumindest bei aktuellen. Da kann man sich sogar Dateien auf Paketen basierend zusammenstellen lassen. Warum nicht bei PHP-Klassen auch?

          In meinem Projekt benötige ich z.B. eine Möglichkeit, eine Excel-Datei auszulesen. Dazu habe ich eine Klasse gefunden, die nur eine weitere einbindet. Da war es kein Problem, den Inhalt der zweiten Datei an das Ende der ersten anzuhängen. Da war es auch klar, dass immer beide Dateien (Klassen) benötigt werden. Um eine MP3-Datei aus mehreren Einzeldateien zusammenzufügen war sogar in einer Einzeldatei als Klasse möglich! Aber bei diesen Mailern... da sehe ich vor lauter Wald keine Bäume!

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. hi,

            Lieber tami,

            Es steht Dir doch aber frei, Dir das zusammenzukopieren in ein File. Soooo viele Abhängigkeiten sollten das mWn. nich sein.

            bei JS-Bibliotheken bekommt man ja auch minifizierten Code - zumindest bei aktuellen. Da kann man sich sogar Dateien auf Paketen basierend zusammenstellen lassen. Warum nicht bei PHP-Klassen auch?

            In meinem Projekt benötige ich z.B. eine Möglichkeit, eine Excel-Datei auszulesen. Dazu habe ich eine Klasse gefunden, die nur eine weitere einbindet. Da war es kein Problem, den Inhalt der zweiten Datei an das Ende der ersten anzuhängen. Da war es auch klar, dass immer beide Dateien (Klassen) benötigt werden. Um eine MP3-Datei aus mehreren Einzeldateien zusammenzufügen war sogar in einer Einzeldatei als Klasse möglich! Aber bei diesen Mailern... da sehe ich vor lauter Wald keine Bäume!

            Das liegt vielleicht daran, dass du mit dem Zend-Framework ja alles was möglich ist geliefert bekommst:

            http://framework.zend.com/manual/1.12/de/zend.mail.introduction.html

            Dafür ist die Bedienung dann ziemlich "idiotensicher" ...;

            mfg

            tami

            1. hi,

              Das liegt vielleicht daran, dass du mit dem Zend-Framework ja alles was möglich ist geliefert bekommst:

              http://framework.zend.com/manual/1.12/de/zend.mail.introduction.html

              mal abgesehen davon, dass es schon länger eine 2.?? -Version gibt:

              http://www.developers-guide.net/c/160-zend-framework-einfacher-e-mail-versand-ueber-zend_mail.html#benoetigt

              mfg

              tami

  2. hi,

    also echo und .= mit Strings ist wirklich schwierig am Ende zu entziffern.

    mit ob_start() und $myText = ob_get_clean() und im Text dann <?php echo $myVar?> hast du zumindest übersichtlichen Code.

    Ansonsten Mail-Klasse vom ZendFramework analysieren: https://github.com/zendframework/zf2

    mfg

    tami

  3. Hi,

    $filename = FILE;

    $content  = chunk_split(base64_encode(file_get_contents($filename)), 76, PHP_EOL);
    #$content = base64_encode(file_get_contents($filename), 76, PHP_EOL);

    $mailto = 'tschmieder@online.de';
    $subject = 'Mail-Test (8) ASCII mit ÄÖÜäöü and boundary';
    $message = 'Hier kommt der öffentliche Text mit dämlichen Übelkeiten und Ödemen';

      
    Das geht schon mal in die Hose. Sobald in Headerzeilen non-ASCII-Zeichen auftauchen, muss der Wert entsprechend codiert werden. [Chris](https://forum.selfhtml.org/?t=216717&m=1486719) hat dir schon gezeigt, wie.  
      
    
    > ~~~php
    
    $header	= "from: info@bikers-lodge.com\n";  
    
    > $time       = time();  
    > $boundary   = "----=_TSMail-Next-Part-$time";  
    >   
    > $header    .= "Content-Type: multipart/mixed;\n";  
    > $header    .= "  boundary=\"$boundary\"\n";  
    >   
    > $message   .= "\n\n--$boundary\n";  
    > $message   .= "Content-Type: text/plain;\n";  
    > $message   .= "  charset=iso-8859-1\n";  
    > $message   .= "Content-Transfer-Encoding: 8bit\n\n";  
    > $message   .= "Test-Mail mit Anhang, bitte den Quelltext der Mail kopieren und nachher mitbringen\n\n";  
    >   
    > $message   .= "\n--$boundary\n";  
    > $message   .= "Content-Type: text/plain;\n";  
    > $message   .= "  name=\"attachment.txt\"\n";  
    > $message   .= "Content-Transfer-Encoding: base64\n";  
    > $message   .= "Content-Disposition: attachment;\n";  
    > $message   .= '  filename="' . basename($filename) . "\"\n\n";  
    > $message   .= $content . PHP_EOL;  
    > $message   .= "\n--$boundary--\n";
    
    

    Und ich bin mir immer wieder unsicher, ob man einfach ungestraft Linefeeds verwenden darf, anstatt der geforderten CR/LF-Kombination.

    Das funktioniert auch soweit, wenn der Client ein Thunderbird ist. Andere konnte ich leider nicht testen im Moment.
    Wenn ich den vermeintlichen Quelltext der empfangenen Mail dann speichere und ihn anschließend mit notepad++ in der Codierung "utf-8 ohne BOM" anschaue, wird auch alles richtig angezeigt.

    Das ist "good will", würde ich sagen. Mit den Non-ASCII-Zeichen im Header sollte man mit allem rechnen.

    Wenn ich mir den Quelltext aber nun anzeigen lassen mit "Thunderbird/Quelltext anzeigen", dann bekomme ich schon wieder Bauchschmerzen:

    Warum? Weil die Non-ASCII-Zeichen nicht korrekt angezeigt werden? Die Codierung der Mail-Header ist nun mal ASCII. Ob 8bit-Codes da inzwischen erlaubt sind oder nur von den meisten MTAs stillschweigend geduldet werden, weiß ich nicht genau. Aber eine Interpretation der Byte-Sequenzen nach UTF-8? Warum? Woher?

    Und woher hat der Mail-Server "Content-Transfer-Encoding: quoted-printable". Hab ich nirgends so angegeben. Ganz im Gegenteil, ich schrieb

    Content-Transfer-Encoding: 8bit\n\n";

    Das hatte ich mir aus einer alten Testmail von OE so rausgepult.

    Das hat dann wahrscheinlich dein lokaler MTA schon umgestellt.

    Ich habe einfach im Moment den Überblick (und das Gedächtnis dafür) verloren, wer an welcher Stelle was verkurbelt, was ich nicht sofort sehe. Da ich keinen näheren Zugriff auf die Mailserver habe (weder Sender, noch Empfänger), kann ich leider auch nicht generisch (mit HEX-Editor) ind die gehandetlen Files reinschauen...

    Nur ganz am Anfang bzw. ganz am Ende der Übertragungskette.

    Ciao,
     Martin

    --
    Wenn man keine Ahnung hat - einfach mal Fresse halten.
      (Dieter Nuhr, deutscher Kabarettist)
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  4. hi, Dein Code ist grausig. Vielleicht kriegst Du den etwas besser hin mit ein bischen Grundlagenverständnis.

    Content-Transfer-Encoding: 8bit
      ist gleich
    Content-Transfer-Encoding: binary

    Unsicher, daher nicht empfehlenswert. Besser

    Content-Transfer-Encoding: quoted-printable
      oder
    Content-Transfer-Encoding: base64

    und hier reden wir nur von den Texten. Quoted-printable ist zu bevorzugen, weil die Mail dann immer noch einigermaßen lesbar, was mit base64 nicht der Fall ist.

    Texte haben eine bestimmte Zeichen-Kodierung, guck:
    Content-Type: text/plain; Charset=UTF-8
      oder
    Content-Type: text/plain; Charset=ISO-8859-1
      o.a.

    Nun, quoted-printable oder base64 (Content-Transfer-Encoding), das wiederum hat mit der Zeichenkodierung überhaupt nichts zu tun, das sind reine Byte-Geschichten. Die Zeichenkodierung kommt erst dann ins Spiel, wenn der MailClient, nach der Übertragung mit einem bestimmten Content-Transfer-Encoding, aus den ankommenden Bytes wieder lesbare Zeichen machen soll.

    Header: Nur Ascii, wurde schon gesagt, Beispiel in Perl
    subject => sprintf("=?%s?Q?%s?=", $in{charset}, $self->quotePrint($in{subject})),

    Heißt: Im Header selbst stehen Charset UND Content-Transfer-Encoding UND nur 7bit-Bytes (ASCII). Wobei das Q für quoted-printable steht, für base64 stünde da ein B

    Spätestens hier sollte Dir klar sein, was Charset und Content-Transfer-Encoding für eine Rolle und wie die zusammenspielen.

    Noch ein Wort zum Code: Mach ein Template, da verlierst Du auch nicht die Übersicht. Übergebe Deinem Konstruktor nicht eine Liste von $from, $to, $subject usw., sondern besser ein assoziatives Array, das macht den Code ungemein lesbarer. Gerade für multipart/mixed und Attachments eignet sich ein Template hervorragend. Baue so die Maildatei zusammen und Pipe auf mta => '/usr/sbin/sendmail -t', das geht auch mit PHP vorzüglich.

    Viel Erfolg!

    1. Hello,

      ach Hotti, wenn ich Dich nicht hätte :-P

      Ist doch nur ein Testfile.

      Und für die Header-Codierung gibt es sogar eine fertige Funktion in PHP, die hatte ich nur noch nicht wieder rausgesucht.

      http://de3.php.net/manual/en/function.mb-encode-mimeheader.php

      Die erwartet aber für den zu codierenden String scheinbar iso-8859-1. Oh Wunder!

        
      $subject 	= mb_encode_mimeheader(utf8_decode('Mail-Test (10) ASCII mit ÄÖÜäöü and boundary'), "UTF-7", "Q". PHP_EOL);  
      
      

      führt jedenfalls zum Erfolg, wenn der Subject-Text in UTF-8 erfasst wurde, was der Fall ist, da die Daten aus der Datenbank kommen, in die sie mit utf-8 reingestopft wurden...

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bikers-lodge.com
      1. hi Du;

        Die erwartet aber für den zu codierenden String scheinbar iso-8859-1. Oh Wunder!

        Nein. mb_encode_mimeheader() erwartet, dass mb_internal_encoding() gesetzt wurde.

        Also machen wir das mal und gucken Ergebnis:

          
        mb_internal_encoding("UTF-8");  
        echo mb_encode_mimeheader(utf8_decode('€')), "\n";  
        echo mb_encode_mimeheader('€');  
        
        

        Siehst Du was? '4oKs' ist die korrekte Base64-Kodierung für das EUR-Zeichen. Wenn Du vorher ein utf8_decode('€') schaltest, ist das Ergebnis nur ein Byte, darstellbar als Fragezeichen oder als Base64 'Pw=='.

        Die Funktionen machen schon das Richtige, Du musst die nur richtig anwenden.

        Horst