4

I made an HTML e-mail send with PHP, but my client receives this as pure code. Here is the PHP code to send the mail:

$subject = 'HTML e-mail test';
$message = '<html>
    <body>
        <h1>TEST</h1>
    </body>
</html>';
$headers = "MIME-Version: 1.0\r\n"; 
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "To: <".$to.">\r\n"; 
$headers .= "From: <".$email.">\r\n";

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

It works fine for me, but they receive it as:

Content-type: text/html; charset=iso-8859-1

To: <email@email.com>
From: <email@email.com>

<html>
    <body>
        <h1>TEST</h1>
    </body>
</html>

Is there something wrong with my headers? Or is it their Outlook? How can I fix this problem?
Thanks in advance!

Jay Wit
  • 2,987
  • 7
  • 32
  • 34
  • Please use an array, or even nowdoc syntax for long blobs like this. http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.nowdoc – Incognito Aug 22 '12 at 12:27
  • @Incognito - The headers in `mail()` come as a string, not an array, and officially are supposed to have lines terminated with `\r\n` (not just your system's idea of a newline). Unless you're thinking of `implode()`ing them on-the-fly? How would you ensure that a nowdoc had the correct line endings? – ghoti Aug 22 '12 at 13:20
  • @ghoti I'm speaking with regards to his string building operations with `.=`. The array would provide a meaningful abstraction would could at-least include logic help prevent things like the `TO: ` field being provided `bob@example.com\r\nTo: billgates@microsoft.com\r\n\r\nSpamSpamSpam\r\n.\r\n\r\n`. --Also, just using geat existing solutions like you suggested below is preferred. – Incognito Aug 22 '12 at 15:55

6 Answers6

3

I see:

Content-typetext/html; charset=iso-8859-1

where I should see:

Content-type: text/html; charset=iso-8859-1

Is that a cut/paste error? In your code, or in your result?

Note that you probably want to include both text/plain and text/html types in a multipart message, since HTML-only mail often gets high spam scores (using SpamAssassin, SpamBouncer, etc).

UPDATE #1:

It appears that the \r\n is being interpreted as two newlines instead of one. Different platforms may have different bugs in their implementation of SMTP. It's possible that you can get away with changing your line endings to just \n. If that works with your system, don't rely on it, as it may not work on a different system.

Also, consider switching to a different method for sending mail. phpMailer and SwiftMailer are both recommended over PHP's internal mail() function.

UPDATE #2:

Building on Incognito's suggestion, here's code you might use to organize your headers better, as well as create a plaintext part:

filter_var($to, FILTER_VALIDATE_EMAIL) or die("Invalid To address");
filter_var($email, FILTER_VALIDATE_EMAIL) or die("Invalid From address");

$subject = 'HTML e-mail test';

$messagetext = 'TEST in TEXT';

$messagehtml = '<html>
    <body>
        <h1>TEST</h1>
        <p>in HTML</p>
    </body>
</html>';

// We don't need real randomness here, it's just a MIME boundary.
$boundary="_boundary_" . str_shuffle(md5(time()));

// An array of headers. Note that it's up to YOU to insure they are correct.
// Personally, I don't care whether they're a string or an imploded array,
// as long as you do input validation.
$headers=array(
    'From: <' . $email . '>',
    'MIME-Version: 1.0',
    'Content-type: multipart/alternative; boundary="' . $boundary . '"',
);

// Each MIME section fits in $sectionfmt.
$sectionfmt = "--" . $boundary . "\r\n"
      . "Content-type: text/%s; charset=iso-8859-1\r\n"
      . "Content-Transfer-Encoding: quoted-printable\r\n\r\n"
      . "%s\n";

$body = "This is a multipart message.\r\n\r\n"
      . sprintf($sectionfmt, "html", $messagehtml)
      . sprintf($sectionfmt, "plain", $messagetext)
      . "--" . $boundary . "--\r\n";

$mailb = mail($to, $subject, $body, implode("\r\n", $headers));

I'm not saying this is The Right Way to do this by any means, but if the strategy appeals to you, and you think you can maintain code like this after not having looked at it for 6 or 12 months (i.e. it makes sense at first glance), then feel free to use or adapt it.

Disclaimer: this is untested, and sometimes I make typos ... just to keep people on their toes. :)

ghoti
  • 45,319
  • 8
  • 65
  • 104
  • Sorry that was a typo, but that's how they receive it. – Jay Wit Aug 22 '12 at 11:54
  • It was a cut/paste(type) error, in the code it's normal. They receive the HTML message as code like in my second example, without markup. How can I send a plain-text message aswell? – Jay Wit Aug 22 '12 at 12:04
0

One good way to be sure is to change your headers to that of this:

$to = 'bob@example.com';

$subject = 'Website Change Reqest';

$headers = "From: " . strip_tags($_POST['req-email']) . "\r\n";
$headers .= "Reply-To: ". strip_tags($_POST['req-email']) . "\r\n";
$headers .= "CC: susan@example.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

Also, double check the rest of your code by comparing to this:

http://css-tricks.com/sending-nice-html-email-with-php/

user1477388
  • 20,790
  • 32
  • 144
  • 264
0

I would recommend not using PHP's mail() function. Yes, it can send an email, but for anything with any kind of complexity, it just makes things difficult.

I'd suggest using a class such as phpMailer, which will give you a lot more flexibility. It makes it much easier to do things like sending HTML emails, adding attachments, and using alternative MTAs.

SDC
  • 14,192
  • 2
  • 35
  • 48
  • Thank you for your answer, I agree that the PHP mail function is 'corrupted', but doesn't the PHP mail function simply work? Like in my example. – Jay Wit Aug 22 '12 at 12:01
  • The formatting of mail headers is an arcane art form. PHP's `mail()` function expects you to know how to do it and get it right. Yes it does work, but phpMailer frees you from the hassle. – SDC Aug 22 '12 at 12:16
0

I've had this issue myself, it was fixed by using \n instead of \r\n. I only use \r\n for the last line in the header.

Rick Kuipers
  • 6,616
  • 2
  • 17
  • 37
0

The problem is that some antivirus email scanners treat anything following the mime header as body text.

The fix is to make you mime header the last one.

I just had the same problem with one of my clients and it had me whacked for a while.

0

This is a problem with Microsoft Outlook (Windows).

The solution is to remove the "\r" at the end of the headers and just use "\n".

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • This may answer the question, but it is buried within unimportant information (such as "I had this problem). Please try to be more clear in future posts (I have attempted to edit, please review this as well). – BradleyDotNET May 20 '14 at 17:11