Problem mit sendmail und PHP
TobAd
- php
Einen schönen guten Abend - oder Morgen... je nachdem.
Ich habe folgendes Problem:
Ich möchte einen Newsletter von einem PHP-Skript aus verschicken. Die Emailadressen lese ich dazu aus einer MySQL-Datenbank aus und führe per while-Schleife diesen Code aus:
$to = $versand['email']; //liest aus der DB die Emailadresse
$headers['From'] = 'newsletter@beispiel.de';
$headers['Subject'] = $text_header; //der Betreff (auch aus einer Abfrage)
$mime = new Mail_mime;
$text = strip_tags($text_text); //der nicht-HTML-Text (auch aus einer Abfrage)
$mime ->setTXTBody($text);
$html = '<html>
<body>
<table width="100%">
<tr bgcolor="#f6821f">
<td height="98"><img src="newsletter_oben.jpg"></td>
</tr>
<tr bgcolor="#fbcda5" align="left">
<td>
<font face="Arial, Helvetica,sans-serif"> '.$text_text.'
</font>
</td>
</tr>
<tr bgcolor="#f6821f">
<td height="102"><img src="newsletter_unten.jpg"></td>
</tr>
</table>
</body>
</html>';
$mime->addHTMLImage("../img/newsletter_oben.jpg", "image/jpeg", "newsletter_oben.jpg");
$mime->addHTMLImage("../img/newsletter_unten.jpg", "image/jpeg", "newsletter_unten.jpg");
$mime->setHTMLBody($html);
$body = $mime->get();
$headers = $mime->headers($headers);
$params['sendmail_path'] = '/usr/sbin/sendmail';
$params['sendmail_args']= '-t -oi';
$message =& Mail::factory('sendmail', $params);
$send = $message->send($to, $headers, $body);
if (PEAR::isError($send)) { print($send->getMessage());}
Problem: Es wird nur der Betreff in Thunderbird angezeigt, nicht jedoch der Text (weder in plain, noch in HTML). Wenn ich direkt auf einen Webmailer (von web.de) gehe, dann zeigt er die Mail (fast) korrekt an. Das einzige, was falsch dargestellt wird, ist die fehlende Hintergrundfarbe der <tr>-Tags (die sollte orange sein, identisch mit der Hintergrundfarbe des Bildes).
Wenn ich die gesendete Mail aus Thunderbird exportiere und mit nem Texteditor öffne, dann tauchen da auf jeden Fall die Infos auf (ich bin mit dem Protokoll nicht ganz vertraut), also plain-text, html-text, die Codierung der Bilder, etc. Wo muss ich da suchen, wenn ich einen Fehler finden möchte?
Ich bin mir nicht sicher, ob das ein spezielles Problem von Thunderbird ist, aber wenn dies der Fall ist, muss ich das nicht in meinem Code abfangen? Und wenn ja, wie?
Sollte an dem Vorgehen etwas von vorneherein unpraktisch oder nicht so sinnvoll sein, dann freue ich mich über kritisches Feedback. Bin zwar kein absoluter Neuling, aber man lernt nie aus.
Der Code ist aus dem Sklar-PHP-Kochbuch.
Vielen Dank für die Mühe!
TobAd
Hallo,
naja, fein ist immer, sich nur um _ein_ problem zu kümmern. also bastel dir doch ein ganz kleines script, was nur mal eine Mail verschicken soll. Dass "nur" TB ein Problem hat, kann ich nicht glauben. Der stellt doch sonst vieles korrekt dar und ist doch weit verbreitet. Da du PEAR-Klassen nutzt, müsste auch das eigentlich erstmal stimmig sein. Insofern GOTO SatzNr1: Alles rausschmeißen und nur das testen was falsch ist.
Gruß
jobo
Hello,
wie sieht denn die generierte eMail aus? Kannst Du mal eine ganz einfache (ohne Monsterbilder) als Textdatei irgendwo berietstellen?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo!
Entschuldigung, dass ich so lange nicht geschrieben habe, war vom Internet abgeschottet...
Vielen Dank für die Rückmeldung, ich habe es nach dem Trial and Error Prinzip versucht und bin dann doch fündig geworden:
Der Code funktioniert so, wie er hier steht, wenn man
$mime = new Mail_mime;
durch
$mime = new Mail_mime("\n");
ersetzt.
Erklärung laut PEAR-Manual:
Pear-Manual
siehe unter "Note".
Vielen Dank nochmal!
Grüße,
TobAd
Hello,
Vielen Dank für die Rückmeldung, ich habe es nach dem Trial and Error Prinzip versucht und bin dann doch fündig geworden:
Der Code funktioniert so, wie er hier steht, wenn man
$mime = new Mail_mime;
> durch
> ~~~php
$mime = new Mail_mime("\n");
>
ersetzt.
Erklärung laut PEAR-Manual:
Pear-Manual
siehe unter "Note".
Das ist nur die halbe Wahrheit.
Besser ist es, die Konstante PHP_EOL zu benutzen als Parameter für den Aufruf. Die passt dann wenigstens fast immer.
Zur Erläuterung:
Wenn Mails über das (Linux-)Sendmail-Script versendet werden, erwartet dieses Linux-konforme Zeilenumbrüche (LF) und ersetzt diese dann nach RFC 2822 für den Internet-Mail-Transport durch CRLF. Leider ersetzt das Script sowohl CR als auch LF durch CRLF, sodass es dann durch die Doppelung zu Fehlern führt.
Wenn man Mails über den SMTP-Server (z.B. Port 25) versendet, erwartet dieser bereits eine RFC-2822-konforme Maildatei. Diese _muss_ nun also CRLF für alle Zeilenünbrüche in den Mail-Headern verwenden. Der Versand über Port25 wird auf Windows-Systemen verwendet.
Die Konstante PHP_EOL enthält nun bei Linux-Installationen gerade LF und bei Windows-Installationen CRLF. Bei MAC konnte ich die Sachlage noch nicht überprüfen.
Wenn Du dein Script also sowohl für Linux-, als auch für Windows-Installationen lauffähig halten willst, ohne basteln zu müssen, dann benutzte die Konstante.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Wenn Mails über das (Linux-)Sendmail-Script versendet werden, erwartet dieses Linux-konforme Zeilenumbrüche (LF) und ersetzt diese dann nach RFC 2822 für den Internet-Mail-Transport durch CRLF. Leider ersetzt das Script sowohl CR als auch LF durch CRLF, sodass es dann durch die Doppelung zu Fehlern führt.
Nicht alle sendmail-Nachahmer machen das so stur. Die meisten sind durchaus intelligent und erkennen CRLFs. Eigentlich kann man bedenkenlos nur die \n verwenden, denn die mail()-Implementation von PHP verwendet genau nur dieses beim Zusammenstellen der Mail. Wenn man also systemkonform unter Windows \r\n einfügt, ist das zwar nett, aber durch PHPs interne Nur-\n hinfällig.
Bei MAC konnte ich die Sachlage noch nicht überprüfen.
Macs sind schon seit geraumer Zeit Linux/Unix-kompatibel.
Lo!