Search code examples
phphtmlemailmime

MIME for Text and HTML emails


How do I modify this code to add MIME and include a text version of the email? As is the code is successfully sending out an HTML formatted email. I am using a text editor, PHP, HTML and a mySQL database. (The purpose of this code is to email a newly registered user a link to use to verify the email address provided during the registration process.)

$first_name =$register_data['first_name'];
$to         =$register_data['email'];
$from       ='support@mysite.com';
$subject    = 'Verify email address to activate account';
$email_code =$register_data['email_code'];

$headers    = "From: $from\r\n";
$headers    .= "Content-type: text/html\r\n";

$path       ="activate.php?email=" . $to . "&email_code=" . $email_code . "";

$message    = <<<EOF
    <html>
        <head>
            <base href="https://mysite.com">
        </head>
        <header>
            <img src="images/logo.png"><br>
            <img src="images/header.png">
        </header>
        <body>
            <br>
            <table style="width:600px">
                <tr>
                    <td style="width:10px"></td>
                    <td>Dear $first_name,</td> 
                    <td style="width:10px"></td>
                </tr>
                <tr></tr>
                <tr>
                    <td></td>
                    <td>Thank you for registering!  To activate your account, please verify your email address address by clicking on the verify button below.</td>
                    <td></td>
                </tr>
            </table>
            <p>
            <table style="width:600px">
                <tr>
                    <td style="width:10px"></td>
                    <td><center><a href =$path><img src="images/verify_button.png"></a></center></td>
                    <td style="width:10px"></td>
                </tr>
            </table>
            </p>
            <p>
            <table style="width:600px">
                <tr>
                    <td style="width:10px"></td>
                    <td>Thanks for registering!</td> 
                    <td style="width:10px"></td>
                </tr>
                <tr>
                    <td style="width:10px"></td>
                    <td>-- mysite</td> 
                    <td style="width:10px"></td>
                </tr>
            </table>
            </p>
        </body>
    </html>
EOF;

mail ($to, $subject, $message, $headers);

Solution

  • MIME Syntax

    This is what the structure of a multi-part message body looks 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 "--"
    

    Note also that each line in the message MUST be terminated with a CRLF-pair (eg. "\r\n") and MUST NOT exceed 1000 characters (including CRLF). This is usually not a problem with text/plain or text/html but when in doubt, use chunk_split (base64_encode ()) on the body-part and add the Content-transfer-encoding: base64 header for that part.

    The code

    The code below is pretty self-explanatory:

    $first_name =$register_data['first_name'];
    $to         =$register_data['email'];
    $from       ='support@mysite.example';
    $subject    = 'Verify email address to activate account';
    $email_code =$register_data['email_code'];
    
    $boundary = md5(uniqid()); /* Unlikely to match any of body parts. */
    
    $headers = "From: $from\r\n"
             . "MIME-Version: 1.0\r\n"
             . "Content-Type: multipart/alternative; boundary=\"$boundary\"\r\n";
    
    $text_msg = <<<EOF
    Your text message.
    EOF;
    
    $html_msg = <<<EOF
    <html><title>Title</title><p>Your HTML message.
    EOF;
    
    $body = "--$boundary\r\n"         /* dash-boundary */
          . "Content-Type: text/plain\r\n"
          . "\r\n"
          . $text_msg
          . "\r\n--$boundary\r\n"     /* delimiter */
          . "Content-Type: text/html\r\n"
          . "\r\n"
          . $html_msg
          . "\r\n--$boundary--\r\n";  /* close-delimiter */
    
    mail ($to, $subject, $body, $headers);
    

    References

    The full details can be found in: