Forum Moderators: coopster
I've got a script that will send a plain text email with one or more attachments which works. But part of the spec for this script is that a bunch of different headers need to be included as well (i.e. Reply To: Reply Path: X-MSmail-Priority: High, and others - see script below).
If I send an email with this script that DOESN'T have an attachment, all is well - all required headers are included and the email is received by the recepiant.
HOWEVER, everytime I send an email that has an attachment AND includes any header data other than "From:", the attachment - as well as the attachment mime headers - ends up IN THE BODY of the email as a mile-long list of garbage characters.
After much testing, this attachment problem "seems" to be caused by by EOL characters "\r\n" at the end of basic email headers.
PROBLEM RECAP:
- Plain Text email WITHOUT attachments: all headers can be included without problem
- Plain text email WITH attachment(s): all headers except for From: need to be stripped, INCLUDING the "\r\n" characters at the end of the the From: header.
Has anyone else had this problem?
I've included my script below in hopes that someone can guide me as to how to I can include all client-required email headers ALONG WITH an email attachment.
Note: As seen below, all additional general email headers have been commented out.
Great appreciation in advance for any assistance!
Neophyte
*********************************************
function send_mail($fName, $fAdd, $tName, $tAdd, $subj, $body, $cName, $cAdd, $bName, $bAdd, $eType, $attach)
{
# TRANSFER $body VAR INTO $message VAR
$message = $body;
//$headers .= 'To: '. $tName . '<' . $tAdd . '>'. "\r\n";
$headers .= 'From: '. $fName . '<' . $fAdd . '>';
//$headers .= 'Reply-To: '. $fName . '<' . $fAdd . '>'. "\r\n";
//$headers .= 'Return-Path: '. $fName . '<' . $fAdd . '>'. "\r\n";
//$headers .= 'Message-ID: <'. time() . '-' . $fAdd . '>'. "\r\n";
//$headers .= 'X-Mailer: PHP v'. phpversion(). "\r\n";
//$headers .= 'X-Priority: 1'. "\r\n";
//$headers .= 'X-MSmail-Priority: High'. "\r\n";
#INCLUDE CC AND BCC IF REQUIRED
//if($cName) $headers .= 'Cc: ' . $cName . '<' . $cAdd . '>'. "\r\n";
//if($bName) $headers .= 'Bcc: '. $bName . '<' . $bAdd . '>'. "\r\n";
#CHECK IF ATTACHMENT IS REQUIRED
#IF TRUE, TRANSFER VARS FROM $_FILES INTO LOCAL COUNTERPARTS
if($attach)
{
$fileatt = $_FILES['UpLoad']['tmp_name'][0];
$fileatt_type = $_FILES['UpLoad']['type'][0];
$fileatt_name = $_FILES['UpLoad']['name'][0];
}
# CHECK IF FILE UPLOAD IS TRUE
if(is_uploaded_file($fileatt))
{
# READ THE FILE TO BE ATTACHED
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);
# GENERATE BOUNDARY STRING
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
# ADD FILE ATTACHMENT HEADERS
$headers .= "\r\nMIME-Version: 1.0\r\n" .
"Content-Type: multipart/mixed;\r\n" .
" boundary=\"{$mime_boundary}\"";
# ADD MULTIPART BOUNDARY ABOVE PLAIN MESSAGE
$message = "This is a multi-part message in MIME format.\r\n\r\n" .
"--{$mime_boundary}\r\n" .
"Content-Type: text/plain; charset=\"iso-8859-1\"\r\n" .
"Content-Transfer-Encoding: 7bit\r\n\r\n" .
$message . "\r\n\r\n";
# BASE64 ENCODE ATTACHMENT FILE DATA
$data = chunk_split(base64_encode($data));
# ADD FILE ATTACHMENT TO THE MESSAGE
$message .= "--{$mime_boundary}\r\n" .
"Content-Type: {$fileatt_type};\n" .
" name=\"{$fileatt_name}\"\r\n" .
"Content-Disposition: attachment;\r\n" .
" filename=\"{$fileatt_name}\"\r\n" .
"Content-Transfer-Encoding: base64\r\n\r\n" .
$data . "\r\n\r\n" .
"--{$mime_boundary}--\r\n";
}
# MAKE SURE EMAIL USES THE FROM ADDRESS
ini_set('sendmail_from', $fAdd);
# SEND THE EMAIL
mail($tAdd, $subj, $message, $headers);
# RESTORE INITIAL STATE OF INI/SENDMAIL_FROM
ini_restore('sendmail_from');
# IF ATTACHMENT IS TRUE, UNLINK ATTACHMENT
if($attach) unlink($filePath);
}
$headers .= "\r\nMIME-Version: 1.0\r\n" .
X-MSmail-Priority: High<CR><LF>
<CR><LF>
MIME-Version: 1.0<CR><LF>
If you aren't familiar with SMTP, "\r\n\r\n" marks the end of the headers, and so causes mail programs to think everything from "MIME-Version" on down is the e-mail. Outputting a single end-of-line (e.g., always at the end of a line, or always at the beginning of a line) will probably fix your problem.
However, as vincevincevince mentioned, there already exist PHP classes to do all this grunt work for you. That's almost certainly the easiest way to go.
rocknbil: "\n" is perl's "logical newline", and so follows the convention of the underlying system for line separator. E.g., on Windows "\n" really means "\r\n", which means "\r\n" is really "\r\r\n". see perlport Newlines [perldoc.perl.org] for the gory details. (Of course, if you're just shelling out to sendmail, single LFs should be fine.)