4

I am going to try this one more time with a very basic example. When I send an e-mail using PHP to e-mail clients, I have no problem except with gmail. When I view the e-mail in gmail, all I see is the code of the message. Gmail does not display the HTML. It just displays the code. Here is my script:

<?php
$to = "someone@gmail.com";
$subject = "Test HTML E-mail";
$random_hash = md5(date("r", time()));
$mID = md5($to);
$headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\n";
$headers .= "Errors-To: someone@yahoo.com" . "\n";
$headers .= "MIME-Version: 1.0" . "\n";
$headers .= "Content-Type: multipart/alternative; boundary=". $random_hash ." ; Message-ID: <" . $mID . ">" . "\n"; 
ob_start();
?>
--<?php echo $random_hash; ?> 
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello, Tom!!! 
This is simple text email message.

--<?php echo $random_hash; ?> 
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!doctype html>
<head>
<title>Untitled Document</title>
</head>
<body>
<h2>Hello, Tom!</h2>
<p>This is something with <strong>HTML</strong> formatting.</p>
</body>
</html>

--<?php echo $random_hash; ?>-- 

<?php
$message = ob_get_clean();
$mail_sent = @mail( $to, $subject, $message, $headers );
echo $mail_sent ? "Mail sent" : "Mail failed";
?>

I have tried this script without the DOCTYPE and with the DOCTYPE. I do not believe there is anything wrong with the HTML. I believe gmail is not recognizing the boundary string for some reason. Here is what I see when I open the e-mail:

--111f3d21df6a6eb40a42e9337a600c21
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello, Tom!!!
This is simple text email message.

--111f3d21df6a6eb40a42e9337a600c21
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!doctype html>
<head>
<title>Untitled Document</title>
</head>
<body>
<h2>Hello, Tom!</h2>
<p>This is something with <strong>HTML</strong> formatting.</p>
</body>
</html>

--111f3d21df6a6eb40a42e9337a600c21--

Can anyone PLEASE tell me why gmail is rendering the whole message and not encoding the HTML? It is as if gmail does not recognize the boundary string. How do I fix this?

As a side note, yes, this is a basic PHP e-mail script I found on the internet. I have made a few modifications, but it is still not working in gmail. All other e-mail clients render it fine. PLEASE HELP! I am at my wit's end. Thank you.

When I added the $headers line in the code example right below that was submitted by Fred -ii-, gmail rendered the HTML, but it still shows the boundary string and the plain text message also. This is what the e-mail looks like:

--f8451c07b6649388e8938cfa12ea21e6 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 7bit Hello, Greg!!! This is simple text email message. --f8451c07b6649388e8938cfa12ea21e6 Content-Type: text/html; charset=iso-8859-1 Content-Transfer-Encoding: 7bit

Hello, Tom!

This is something with HTML formatting. --f8451c07b6649388e8938cfa12ea21e6--

I hope that comes out right.

Greg G
  • 135
  • 1
  • 11
  • Your initial headers need to contain `$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";` right below `$headers .= "MIME-Version: 1.0" . "\n";` as per http://php.net/mail – Funk Forty Niner Feb 20 '14 at 02:59
  • stop mail() use php mailer or swiftmailer –  Feb 20 '14 at 03:01
  • @Fred -ii I just tried putting that in there. The problem is that is is a multipart message. It has a plain text part and an html part. I have also been told that gmail will not accept the \r character. It causes an extra line to be inserted. That is why I do not have any in my code. – Greg G Feb 20 '14 at 03:11
  • Gmail does accept the `\r` character. I use `\r\n` in all my scripts and all come in OK with all email clients, including Gmail. I even tested my answer below using it in `$headers .= "MIME-Version: 1.0" . "\r\n";` and it came in just fine. – Funk Forty Niner Feb 20 '14 at 03:20
  • @Fred -ii- This is the post that I saw that said not to use the \r in the code. http://stackoverflow.com/questions/10327354/how-to-send-html-emails-to-gmail-with-php-yahoo-works-not-gmail?rq=1 – Greg G Feb 20 '14 at 03:40
  • See **Edit 2** in my answer. And I saw the post, thanks. – Funk Forty Niner Feb 20 '14 at 03:47

2 Answers2

4

Edit #4

Here is another good version and seems easier to work with:

<?php
//define the receiver of the email
$to = 'email@example.com';
//define the subject of the email
$subject = 'Test HTML email';
 
// Generate a random boundary string
$mime_boundary = '_x'.sha1(time()).'x';
 
// Using the heredoc syntax to declare the headers
$headers = <<<HEADERS
From: Test <email@example.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="PHP-alt$mime_boundary"
HEADERS;
 
// Use our boundary string to create plain text and HTML versions
$message = <<<MESSAGE
--PHP-alt$mime_boundary
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
 
This Is a Plain Text Email
 
This message has no HTML. http://www.google.com
 
--PHP-alt$mime_boundary
Content-type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: 7bit
 
<html>
<body>
<h1>This Is an HTML Email</h1>
<p>
This message is composed in <a href="http://www.google.com">GOOGLE, click here</a>.
</p>
</body>
</html>
--PHP-alt$mime_boundary--
MESSAGE;
 
// Send the message
if(!mail($to, $subject, $message, $headers))
{
// If the mail function fails, return an error message
echo "Something went wrong!";
}
else
{
// Return a success message if nothing went wrong
echo "Message sent successfully. Check your email!";
}
?>

Edit 3

Another tested method: (which so far is the better method)

<?php

function send_email(

$to='email@example.com', 
$from='email@example.com', 
$subject='test', 
$html_content='<b>HELLO in HTML bold</b>', 
$text_content='Hi there in plain text', 
$headers='') 

{ 
    # Setup mime boundary
    $mime_boundary = 'Multipart_Boundary_x'.md5(time()).'x';

    $headers  = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: multipart/alternative; boundary=\"$mime_boundary\"\r\n";
    $headers .= "Content-Transfer-Encoding: 7bit\r\n";

    $body    = "This is a multi-part message in mime format.\n\n";

    # Add in plain text version
    $body   .= "--$mime_boundary\n";
    $body   .= "Content-Type: text/plain; charset=\"charset=us-ascii\"\n";
    $body   .= "Content-Transfer-Encoding: 7bit\n\n";
    $body   .= $text_content;
    $body   .= "\n\n";

    # Add in HTML version
    $body   .= "--$mime_boundary\n";
    $body   .= "Content-Type: text/html; charset=\"UTF-8\"\n";
    $body   .= "Content-Transfer-Encoding: 7bit\n\n";
    $body   .= $html_content;
    $body   .= "\n\n";

    # Attachments would go here
    # But this whole email thing should be turned into a class to more logically handle attachments, 
    # this function is fine for just dealing with html and text content.

    # End email
    $body   .= "--$mime_boundary--\n"; # <-- Notice trailing --, required to close email body for mime's

    # Finish off headers
    $headers .= "From: $from\r\n";
    $headers .= "X-Sender-IP: $_SERVER[SERVER_ADDR]\r\n";
    $headers .= 'Date: '.date('n/d/Y g:i A')."\r\n";

    # Mail it out
    return mail($to, $subject, $body, $headers);
}
send_email(); // call the function
?>

Edit 2

This worked, and only showed me in HTML in Gmail, so plain text should theoretically work.

<?php

$notice_text = "This is a multi-part message in MIME format.";
$plain_text = "This is a plain text email.\r\nIt is very cool.";
$html_text = "<html><body>This is an <b style='color:purple'>HTML</b>" .
             "text email.\r\nIt is very cool.</body></html>";

$semi_rand = md5(time());
$mime_boundary = "==MULTIPART_BOUNDARY_$semi_rand";
$mime_boundary_header = chr(34) . $mime_boundary . chr(34);

$to = "Me <email@example.com>";
// $bcc = "You <you@you.com>, Them <them@them.com>";
$from = "Him <another@example.com>";
$subject = "My Email";

$body = "$notice_text

--$mime_boundary
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

$plain_text

--$mime_boundary
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

$html_text

--$mime_boundary--";

if (@mail($to, $subject, $body, 
    "From: " . $from . "\n" . 
    "bcc: " . $bcc . "\n" . 
    "MIME-Version: 1.0\n" . 
    "Content-Type: multipart/alternative;\n" . 
    "     boundary=" . $mime_boundary_header))
    echo "Email sent successfully.";
else
    echo "Email NOT sent successfully!";

?>

Edit 1

Try this version: (tested with no additional codes anywhere)

<?php
$to = "someone@gmail.com";
$subject = "Test HTML E-mail";

$headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";

//unique boundary
$boundary = uniqid("HTMLDEMO");

//tell e-mail client this e-mail contains//alternate versions
$headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

//plain text version of message
$body = "--$boundary\r\n" .
   "Content-Type: text/plain; charset=ISO-8859-1\r\n" .
   "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= chunk_split(base64_encode("

Hello, Tom!!! 
This is simple text email message.

"));

//HTML version of message
$body .= "--$boundary\r\n" .
   "Content-Type: text/html; charset=ISO-8859-1\r\n" .
   "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= chunk_split(base64_encode("

<!doctype html>
<head>
<title>Untitled Document</title>
</head>
<body>
<h2>Hello, Tom!</h2>
<p>This is something with <strong>HTML</strong> formatting.</p>
</body>
</html>


"));
ob_start();

?>

<?php
$message = ob_get_clean();
$mail_sent = mail( $to, $subject, $body, $headers );
echo $mail_sent ? "Mail sent" : "Mail failed";
?>

You need to use the following in your initial headers:

$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

below:

$headers .= "MIME-Version: 1.0" . "\n";

as per the manual on PHP.net

Tested (successfully sent to my Gmail in HTML and not as code)

<?php
$to = "someone@gmail.com";
$subject = "Test HTML E-mail";
$random_hash = md5(date("r", time()));
$mID = md5($to);
$headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\n";
$headers .= "Errors-To: someone@yahoo.com" . "\n";
$headers .= "MIME-Version: 1.0" . "\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=". $random_hash ." ; Message-ID: <" . $mID . ">" . "\n"; 
ob_start();
?>

// rest of code below...
Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • Let me try this. I will copy it and paste it exactly as you have it here. Of course, I will change the e-mail addresses to mine. I'll let you know what happens. Thank you. – Greg G Feb 20 '14 at 03:13
  • I got the html to render, but I am still seeing the boundary string along with the plaintext message. – Greg G Feb 20 '14 at 03:22
  • See my **Edit** I changed it a bit, but it works. @GrG – Funk Forty Niner Feb 20 '14 at 03:36
  • This code works better than my code. It is now displaying the message without the boundary string. The only problem is that it is displaying both the plain text and the HTML text also. Any ideas? – Greg G Feb 20 '14 at 03:52
  • See **Edit 3** it shows only HTML, but then when you view complete headers, it will show the `Hi there in plain text` @GrG – Funk Forty Niner Feb 20 '14 at 03:59
  • Thank you so much! Edit 2 worked perfectly! In both yahoo and gmail, it rendered great. Now I can tryto modify this script to send more complex HTML emails. Thank you so much for all your help! I also accepted your answer on this post. – Greg G Feb 20 '14 at 04:03
  • You're very much welcome, glad I could help. And method # 3 is not bad also. @GrG – Funk Forty Niner Feb 20 '14 at 04:04
  • I stumbled upon what seems to be a much easier version. See **Edit #4** @GrG – Funk Forty Niner Feb 20 '14 at 04:23
1

Well , I got it working just by adding these three lines of headers , so give it a try and let me know

$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

// More headers
$headers .= 'From: <example@gmail.com>' . "\r\n";

DEEPAK
  • 1,364
  • 10
  • 24