Der Martin: mail mit eingebettetem Bild versenden

Beitrag lesen

Hallo Jörg,

ich versuche gerade, eine mail mit eingebettetem Bild zu versenden. Das ganze soll so ablaufen, daß in der mail zuerst das Bild und darunter ein Text angezeigt werden soll.

also wirst du nicht vermeiden können, das Ding als HTML-Mail zu verschicken. Denn andernfalls hast du nur den Grundaufbau Text+Attachment(s) ohne eine feste, vorgegebene Reihenfolge oder Beziehung.

Ich habe daher einen Script im Internet gefunden, den ich ergänzt habe.

*EIN* Script, nicht EINEN.
Und jetzt ein paar Anmerkungen zum Code.

$Empfaenger = "x.y@z.de";
$Betreff = "Meine erste Mail mit Anhang";
$Dateiname = "poster.gif";
$DateinameMail = "Poster.gif";

Wozu verschiedene Dateinamen? Und dann noch mit der ungewöhnlichen (und ungeliebten) Großschreibung?

$Header = "From: Mein Name meine@mailadresse.de";
$Trenner = md5(uniqid(time()));
$Header .= "\n";

Bingo, Fehler. Als Zeilenumbruch in Mail-Headern ist die Sequenz CR+LF vorgeschrieben. Die meisten MTAs akzeptieren zwar auch ein einzelnes LF, aber darauf darf man sich nicht verlassen.
Außerdem ein guter Rat: Es macht den Code übersichtlicher, wenn man den Zeilenumbruch gleich in derselben Zeile mit angibt, anstatt ihn separat im Script zu verstreuen:

$Header = "From: Mein Name meine@mailadresse.de\r\n";

$Header .= "Content-Type: multipart/mixed; boundary=$Trenner";
$Header .= "\n\n";

Richtiger wäre hier der Content-Type "multipart/related". Dein Ansatz mit "multipart/mixed" würde heißen, dass mehrere Teile vorliegen, die alle gleichrangig sind, aber nichts miteinander zu tun haben (z.B. Text und mehrere Anhänge).

Außerdem beendest du mit dem doppelten Zeilenumbruch die Header, was danach folgt, ist eigentlich der Mail-Inhalt (mail body). Diesen ebenfalls noch dem "Header" zuzuordnen, ist zumindest irreführend. Technisch macht es keinen Unterschied, weil die Bestandteile nachher sowieso alle sequentiell aufeinander folgen, aber es ist halt unsauber.

$Header .= "This is a multi-part message in MIME format";
$Header .= "\n";
$Header .= "--$Trenner";
$Header .= "\n";
$Header .= "Content-Type: text/html";
$Header .= "\n";
$Header .= "Content-Transfer-Encoding: 8bit";
$Header .= "\n\n";
$Header .= "<body text='#FFFFFF' bgcolor='#000000'>";

Spannende Frage: Wie referenzierst du das Bild innerhalb deines HTML-Teils? Richtig wäre die Form  <img src="cid:identifier" ... >, wobei identifier ein beliebig wählbarer String ist, der im nächsten Teil der Mail (dem Bildanhang) wieder auftaucht. Schau dir das mal im Quellcode einer HTML-Mail an, die z.B. mit Outlook oder Outlook Express erzeugt wurde. Das Prinzip dürfte schnell deutlich werden.

$Header .= "\n";
$Header .= "--$Trenner";
$Header .= "\n";
$Header .= "Content-Type: image/gif; name=$DateinameMail";
$Header .= "\n";
$Header .= "Content-Transfer-Encoding: base64";
$Header .= "\n";
$Header .= "Content-Disposition: inline; filename=$DateinameMail";
$Header .= "\n\n";

Anstatt "Content-Disposition:" genügt hier ein einfaches "Content-ID: identifier", wobei hier genau der String definiert wird, mit dem du im HTML-Teil das Bild referenzierst. Einen Dateinamen braucht das Bild hier nicht, weil es über die Content-ID (cid) direkt referenziert wird.

$Header .= "--$Trenner--";
$Header .= "\n\n";
$Header .= "Content-Type: text/html";
$Header .= "\n\n";
$Header .= "<b>Hier folgt weiterer Text";

Warum das? Diesen "weiteren Text" kannst du doch bereits im ersten HTML-Teil unterbringen. Ganz abgesehen davon, dass ein HTML-Dokument mit <html> oder besser noch mit einem <!DOCTYPE> beginnt. HTML-Mails mit mehreren HTML-Teilen sind AFAIK nicht vorgesehen, und außerdem sagst mit mit den zwei '-' hinter dem $Trenner, dass der Block "multipart/*" hier zu Ende ist - deshalb wohl auch:

  1. Der abschließende Text "Hier folgt weiterer Text" erscheint nicht.

mail($Empfaenger, $Betreff, "", $Header);

Und hier sieht man nochmal, wie du die Zuordnung von Header und Inhalt durcheinanderbringst: Du versendest eine Mail ohne Inhalt, aber dafür mit elend langem Header. Das funktioniert nur deshalb, weil du den doppelten Zeilenumbruch bereits *innerhalb* der Header hast und so die Zuordnung wiederherstellst. Schön ist das aber nicht.

So long,
 Martin

--
Kleine Geschenke erhalten die Freundschaft.
Große verderben sie aber meist auch nicht.