Michael Hofer: pdf-Datei per mail versenden

Hallo!

Ich möchte gerne eine pdf-Datei per mail versenden.

Habe das folgende Script.

Wenn ich nur die Datei versende funktioniert es einwandfrei. Sobald ich aber eine Mehrteilige nachricht versende funktioniert es nicht mehr.

Kann mir bitte jemand sagen wo der Fehler in meinem Code ist.

mfg Michael

$boundary = strtoupper(md5(uniqid(time())));
$mail_header  = "From:HOFERNET <$from>\n";
$mail_header .= "MIME-Version: 1.0";
$mail_header .= "\nContent-Type: multipart/mixed; boundary=$boundary";
$mail_header .= "\n\nThis is a multi-part message in MIME format  --  Dies ist eine mehrteilige Nachricht im MIME-Format";
$mail_header .= "\n--$boundary";

$file_content = fread(fopen($file,"r"),filesize($file));
$file_content = chunk_split(base64_encode($file_content));
$mail_header .= "\nContent-Type: application/pdf; name="$file_name"";
$mail_header .= "\nContent-Transfer-Encoding: base64";
$mail_header .= "\nContent-Disposition: attachment; filename="$file_name"";
$mail_header .= "\n\n$file_content";
$mail_header .= "\n--$boundary";

$mail_header .= "\nContent-Type: text/plain";
$mail_header .= "\nContent-Transfer-Encoding: 8bit";
$mail_header .= "\n\n$message";
$mail_header .= "\n--$boundary";

mail($to,$betreff,$message,$mail_header);

  1. Hello,

    Hallo!

    Ich möchte gerne eine pdf-Datei per mail versenden.

    Habe das folgende Script.

    Wenn ich nur die Datei versende funktioniert es einwandfrei. Sobald ich aber eine Mehrteilige nachricht versende funktioniert es nicht mehr.

    Kann mir bitte jemand sagen wo der Fehler in meinem Code ist.

    mfg Michael

    $boundary = strtoupper(md5(uniqid(time())));
    $mail_header  = "From:HOFERNET <$from>\n";
    $mail_header .= "MIME-Version: 1.0";
    $mail_header .= "\nContent-Type: multipart/mixed; boundary=$boundary";
    $mail_header .= "\n\nThis is a multi-part message in MIME format  --  Dies ist eine mehrteilige Nachricht im MIME-Format";

    $mail_header .= "\n--$boundary";  ### Leerzeile?

    $file_content = fread(fopen($file,"r"),filesize($file));
    $file_content = chunk_split(base64_encode($file_content));
    $mail_header .= "\nContent-Type: application/pdf; name="$file_name"";
    $mail_header .= "\nContent-Transfer-Encoding: base64";
    $mail_header .= "\nContent-Disposition: attachment; filename="$file_name"";
    $mail_header .= "\n\n$file_content";
    $mail_header .= "\n--$boundary";

    $mail_header .= "\nContent-Type: text/plain";
    $mail_header .= "\nContent-Transfer-Encoding: 8bit";
    $mail_header .= "\n\n$message";
    $mail_header .= "\n--$boundary";

    mail($to,$betreff,$message,$mail_header);

    sieht eigentlich auf den erste Blick fast gut aus, außer

    • die Zeilenende für Header sind nach Vorschrift CRLF und nicht nur LF
    • bei Chunksplit nun wieder habe ich schon mehrfach ffestsgestellt, dass da nur LF
        als Trenner durchgegangen ist. Irgendwo stand das auch...
        Leider ist da bei PHP die Vorgabe gerade anders herum.
    • Wenn ich mir z.B. von Outlook Express erzeugte Mails anschaue, dann haben die hinter
        einer Boundary auch immer eine Leerzeile...

    Harzliche Grüße vom Berg
    http://bergpost.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

  2. n'Abend!

    Ich möchte gerne eine pdf-Datei per mail versenden.

    Also als Mail-Anhang?

    $boundary = strtoupper(md5(uniqid(time())));
    $mail_header  = "From:HOFERNET <$from>\n";
    $mail_header .= "MIME-Version: 1.0";
    $mail_header .= "\nContent-Type: multipart/mixed; boundary=$boundary";

    Wieso wechselst du hier auf einmal die Position der Zeilenumbrüche? Erst notierst du sie am Ende des Strings, dann plötzlich am Anfang des nächsten. Das ist zwar von der sache her egal, aber es ist übersichtlicher, wenn du bei einer Schreibweise bleibst. Ich selbst würde empfehlen, den Zeilenumbruch auch am Ende einer Anweisung zu notieren, das wirkt übersichtlicher.
    Nicht egal ist allerdings, dass du die Zeilenumbrüche nur mit \n angibst. Laut einschlägigen RFCs müssen Mail-Headerzeilen aber mit \r\n getrennt werden.

    $mail_header .= "\n\nThis is a multi-part message in MIME format  --  Dies ist eine mehrteilige Nachricht im MIME-Format";
    $mail_header .= "\n--$boundary";

    Und es ist unsauber, das alles noch dem Mail-Header zuzuordnen. Alles ab "This is a multi-part ..." ist genaugenommen schon der Message Body.
    Das macht de facto keinen Unterschied, weil mail() sowieso den Header und den Message-Text durch zwei Zeilenumbrüche getrennt aneinanderhängt.

    $file_content = fread(fopen($file,"r"),filesize($file));

    Das ist auch so'n Schönheitsfehler: Die Datei wird nicht geschlossen (okay, das wird am Ende des Scripts automatisch erledigt, ist aber nicht wirklich sauber).

    $mail_header .= "\nContent-Type: text/plain";
    $mail_header .= "\nContent-Transfer-Encoding: 8bit";
    $mail_header .= "\n\n$message";
    $mail_header .= "\n--$boundary";

    Was steht in deinem Fall in $message? Nicht dass das wichtig wäre, aber du hast diese Variable nirgends definiert - jedenfalls nicht in dem Stück Code, das du hier zeigst.

    mail($to,$betreff,$message,$mail_header);

    Und hier verschickst du $message zweimal - einmal bereits in $mail_header eingebettet, und dann nochmal separat. Das zweite Vorkommen dürfte der empfangende Mailclient allerdings ignorieren, weil es nach dem abschließenden Boundary kommt und daher nicht mehr erwartet wird.

    Tja ... abgesehen von \n anstatt \r\n kann ich keinen wirklichen Fehler entdecken, nur eine unsaubere Implementierung ...

    So long,
     Martin

    --
    F: Was ist schneller: Das Licht oder der Schall?
    A: Offensichtlich der Schall. Wenn man den Fernseher einschaltet, kommt immer erst der Ton, und dann erst das Bild.