Search code examples
phpemailmime

MIME Multipart Message in PHP not sending


I am trying to send a MIME Multipart Message in PHP but it is not sending. I have come to the conclusion that this may be because of a problem with the MIME syntax somewhere, but I do not know where.

Here is the code:

$Subject = "****** Contact Form";
$Name = trim(stripslashes($_POST['Name'])); 
$Email = trim(stripslashes($_POST['Email'])); 
$Message = nl2br(trim(stripslashes($_POST['Message'])));
$MessagePlain = trim(stripslashes($_POST['Message']));
$ReferredBy = $_POST['referredby']; 
$Other = trim(stripslashes($_POST['othertext'])); 
$Day = $_POST['Day']; 
$Month = $_POST['month']; 
$Year = $_POST['year']; 

if ($Month = 1) {
        $Month = 'January';
    } elseif ($Month = 2) {
        $Month = 'February';
    } elseif ($Month = 3) {
        $Month = 'March';
    } elseif ($Month = 4) {
        $Month = 'April';
    } elseif ($Month = 5) {
        $Month = 'May';
    } elseif ($Month = 6) {
        $Month = 'June';
    } elseif ($Month = 7) {
        $Month = 'July';
    } elseif ($Month = 8) {
        $Month = 'August';
    } elseif ($Month = 9) {
        $Month = 'September';
    } elseif ($Month = 10) {
        $Month = 'October';
    } elseif ($Month = 11) {
        $Month = 'November';
    } elseif ($Month = 12) {
        $Month = 'December';
}

$MIMEBoundary = md5(uniqid(rand()));

// prepare email headers
$Headers  = "MIME-Version: 1.0\r\n";
$Headers .= "From: ******\r\n";
$Headers .= "Reply-To: ****** <******@hotmail.com>\r\n";
$Headers .= "Content-type: multipart/alternative; boundary=$MIMEBoundary\r\n";

// prepare email body text
$Body = "--" . $MIMEBoundary . "\r\n";
$Body .= "Content-type: text/html;charset=\"ISO-8859-1\"\r\n";
$Body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$Body .= '<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Thank you for your message!</title><style type="text/css"> @media only screen and (max-width: 647px){#container{padding:0 !important;}#header, #header-content, #body, #content, #info, #body-message{width:100% !important;}#body-message, #quote{padding:20px !important;}} </style></head><body style="margin:0;"><table width="100%" height="100%" style="background-color:#fafafa;font-family:Helvetica Neue, Helvetica, sans-serif;padding:45px;" cellpadding="0" cellspacing="0" id="container"><tr><td><table align="center" cellpadding="0" cellspacing="0" border="0" id="rounded-border-top"><tr><td><img src="http://******"/></td></tr></table><table align="center" cellpadding="0" cellspacing="0" border="0" style="border-left:solid 1px #e6e6e6;border-right:solid 1px #e6e6e6;" id="content"><tr><td style="width:600px;background-color:#ffffff;" id="body"><table cellpadding="0" cellspacing="0" border="0" style="padding:45px;color:#303030;line-height:140%;" id="body-message"><tr><td>Hi '.$Name.',<br/><br/> Thank you for your message! I will endeavour to reply to your message within 24 hours. If you have any queries, please feel free to contact me on 07783 962 578.<br/><br/> As a first thanks, here is a free copy of the \'10 top wedding-planning tips\'. It covers the 10 essentials to wedding planning and common mistakes that can be made. Wedding planning is often very stressful, with so many things to think about. So hopefully this little companion will help lessen the load!<br/><br/><a href="downloadfreecopy.html"><img src="http://******" alt="Download Free Copy" style="border:0;"/></a><br/><br/> Best Wishes,<br/><br/><img src="http://******" alt="******"></td></tr></table></td></tr></table><table align="center" cellpadding="0" cellspacing="0" border="0" id="rounded-border-bottom"><tr><td><img src="http://******" align="left"></td></tr></table></td></tr></table></body></html>';
$Body .= "\r\n\r\n--' . $MIMEBoundary . '\r\n";
$Body .= "Content-type: text/plain;charset=\"ISO-8859-1\"\r\n";
$Body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$Body .= 'Hi '.$Name.',

Thank you for your message! I will endeavour to reply to your message within 24 hours. If you have any queries, please feel free to contact me on 07783 962 578.\r\n\r\nAs a first thanks, here is a free copy of the \'10 top wedding-planning tips\'. It covers the 10 essentials to wedding planning and common mistakes that can be made. Wedding planning is often very stressful, with so many things to think about. So hopefully this little companion will help lessen the load!

http://******

Best Wishes,
******';
$Body .= "\r\n\r\n--" . $MIMEBoundary;

$Body2 = "--" . $MIMEBoundary . "\r\n";
$Body2 .= "Content-type: text/html;charset=\"ISO-8859-1\"\r\n";
$Body2 .= "Content-Transfer-Encoding: base64\r\n\r\n";
$Body2 .= '<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Thank you for your message!</title><style type="text/css"> @media only screen and (max-width: 647px){#container{padding:0 !important;}#header, #header-content, #body, #content, #info, #body-message{width:100% !important;}#body-message, #quote{padding:20px !important;}} </style></head><body style="margin:0;"><table width="100%" height="100%" style="background-color:#fafafa;font-family:Helvetica Neue, Helvetica, sans-serif;padding:45px;" cellpadding="0" cellspacing="0" id="container"><tr><td><table align="center" cellpadding="0" cellspacing="0" border="0" id="rounded-border-top"><tr><td><img src="http://******"/></td></tr></table><table align="center" cellpadding="0" cellspacing="0" border="0" style="border-left:solid 1px #e6e6e6;border-right:solid 1px #e6e6e6;" id="content"><tr><td style="width:600px;background-color:#ffffff;" id="body"><table cellpadding="0" cellspacing="0" border="0" style="padding:45px;color:#303030;line-height:140%;" id="body-message"><tr><td>New Message<br/><br/><table width="100%" cellpadding="0" cellspacing="10" border="0" style="width:510px;" id="info"><tr><td width="50%"><strong>Question</strong></td><td width="50%"><strong>Answer</strong></td></tr><tr><td>Name:</td><td>'.$Name.'</td></tr><tr><td>Email:</td><td>'.$Email.'</td><tr><td>Phone:</td><td>'.$Telephone.'</td></tr><tr><td>Referred By:</td><td>'.$ReferredBy.'</td></tr><tr><td>Date:</td><td>'.$Day.' '.$Month.' '.$Year.'</td></tr><tr><td colspan="2">Message:<br/><br/><table width="100%" cellpadding="45" cellspacing="0" border="0" style="background-color:#fafafa;color:#505050;font-size:14px;line-height:140%;"><tr><td>'.$MessagePlain.'</td></tr></table></td></tr></table></td></tr></table></td></tr></table><table align="center" cellpadding="0" cellspacing="0" border="0" id="rounded-border-bottom"><tr><td><img src="http://******" align="left"></td></tr></table></td></tr></table></body></html>';
$Body2 .= "Content-type: text/plain;charset=\"ISO-8859-1\"\r\n";
$Body2 .= "Content-Transfer-Encoding: base64\r\n\r\n";
$Body2 .= 'New Message

Question Answer
Name: '.$Name.'
Email: '.$Email.'
Phone: '.$Telephone.'
Referred By: '.$ReferredBy.'
Date: '.$Day.' '.$Month.' '.$Year.'
Message:
' . $MessageAdmin;
$Body2 .= "\r\n\r\n--" . $MIMEBoundary;

//Send email to user
mail($Email, $Subject, $Body, $Headers);

// send email to admin
mail('******@hotmail.com', $Subject, $Body2, $Headers);


?>

Solution

  • The problem

    There are several problems with your code:

    • The delimiter between the first and second body part is incorrect

      $Body .= "\r\n\r\n--' . $MIMEBoundary . '\r\n";
      

      The line above will output single quotes and dots. It should read:

        $Body .= "\r\n\r\n--" . $MIMEBoundary . "\r\n";
      

      or

        $Body .= "\r\n\r\n--$MIMEBoundary\r\n";
      
    • The close-delimiters in both emails are incorrect

      $Body .= "\r\n\r\n--" . $MIMEBoundary;
      $Body2 .= "\r\n\r\n--" . $MIMEBoundary;
      

      The close-delimiter must end in two dashes, so the lines above should read:

        $Body .= "\r\n\r\n--" . $MIMEBoundary . "--";
        $Body2 .= "\r\n\r\n--" . $MIMEBoundary . "--";
      

      or

        $Body .= "\r\n\r\n--$MIMEBoundary--";
        $Body2 .= "\r\n\r\n--$MIMEBoundary--";
      
    • Incorrect content encoding

      If you specify Content-Transfer-Encoding: base64 you must also base64_encode() (and chunk_split()) that body part.

    See also Final Notes below.

    MIME Syntax

    This is an excerpt of what the structure of a multi-part message body looks like according to RFC 2046. (BNF syntax, somewhat simplified.)

    multipart-body := [preamble CRLF]
                      dash-boundary CRLF
                      body-part *encapsulation
                      close-delimiter
                      [CRLF epilogue]
    
    dash-boundary := "--" boundary
    
    body-part := MIME-part-headers [CRLF *OCTET]
    
    encapsulation := delimiter
                     CRLF body-part
    
    delimiter := CRLF dash-boundary
    
    close-delimiter := delimiter "--"
    

    References

    Final Notes

    • The variables that are expanded inside the HTML email body (eg. $Name etcetera) should be escaped with htmlspecialchars().

    • It would be much easier to understand the structure of the email message if you store each body part in variables:

        $Body  = "--$MIMEBoundary\r\n"; /* First dash-boundary */
        $Body .= "Content-type: text/html;charset=\"ISO-8859-1\"\r\n";
        $Body .= "Content-Transfer-Encoding: base64\r\n";
        $Body .= "\r\n";
        $Body .= $Body_part1;
        $Body .= "\r\n--$MIMEBoundary\r\n"; /* delimiter */
        $Body .= "Content-type: text/plain;charset=\"ISO-8859-1\"\r\n";
        $Body .= "Content-Transfer-Encoding: base64\r\n";
        $Body .= "\r\n";
        $Body .= $Body_part2;
        $Body .= "\r\n--$MIMEBoundary--"; /* close-delimiter */
        /* You only need a single CRLF between body part and delimiter. */
      
    • Personally, I would test if the MIME boundary string occurs in any of the body parts before using it, but then I would also use much shorter boundary strings. But that's just me. Normal people don't do that.