Send Hassle Free and Dependable HTML Emails With PHP
Sunday, January 18th, 2009
No matter what people are telling you, I'll be the first to say it. Plain text e-mails are ugly. Most of your customers/readers/whatever can see HTML messages. So why aren't you sending them? Sexy & colorful HTML e-mails pop off the screen. Plain text e-mails make me fall asleep.
Outside of being sexier, they help with conversion. If you want to send an e-mail with a link back to your Website, how will you accomplish that with plain text? Please don't expect everyone to copy + paste. That's so last year. You're probably not sending HTML e-mails because, until today, the code has been presented in long, drawn out explanations that you have to piece together. Ouch.
So here I am to answer your dreams: A simple straightforward function that sends HTML e-mails with a plain text counterpart for those over 80 and still using AOL 2.5.
Our Script
/*
EXAMPLE: htmlmail('user@domain.com', 'Look ma, HTML e-mails','You just got <a href="http://www.yougotrickrolled.com/">Rick Rolled</a>');
NOTE: $headers is optional, but can be used to set From, CC, etc. Go to http://www.htmlite.com/php029.php for info
*/
function htmlmail($to, $subject, $message, $headers = NULL)
{
$mime_boundary = md5(time());
$headers .= "\nMessage-ID: <" . time() . " TheSystem@{$_SERVER['SERVER_NAME']}>\n";
$headers .= "X-Mailer: PHP " . phpversion() . "\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/alternative;boundary={$mime_boundary}\n\n";
$newmessage = "This is a multi-part message in MIME format.";
$newmessage .= "\n\n--{$mime_boundary}\n";
$newmessage .= "Content-type: text/plain;charset=utf-8\n\n";
$newmessage .= strip_tags(str_replace(array('<br>', '<br />'), "\n", $message)) . "\n\n";
$newmessage .= "\n\n--{$mime_boundary}\n";
$newmessage .= "Content-type: text/html;charset=utf-8\n\n";
// prepended HTML
$newmessage .= '<body style="margin:0"><table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0"><tr><td bgcolor="#ffffff" valign="top"><table width="750" border="0" cellpadding="0" cellspacing="0" align="center"><tr><td bgcolor="#ffffff" width="750">';
// HTML message that was passed to this function
$newmessage .= $message;
// appended HTML
$newmessage .= '</td></tr></table></td></tr></table></body>';
return mail($to, $subject, $newmessage, $headers);
}
There it is! Just copy and paste that bad boy wherever you want and begin using it today. With the prepended and appended HTML I have already in the function, your e-mails will be in a 750 pixel wide container that's centered.
Don't get carried away with your HTML+CSS wizardry, though! The mantra of HTML e-mails is, go back to the basics and don't leave it up to the e-mail client. Here are a few tips to get you rollin' in the right direction:
- Forget everything you know about semantics, XHTML, etc. When it comes to HTML e-mails, this represents best practice:
<table width="750" height="100" border="0" cellpadding="0" cellspacing="0" align="left">. Most e-mail programs won't understand your sophisticated XHTML mumbo jumbo. Use HTML tables to position everything. - Use inline CSS. That's right. Use of the
<style type="text/css">will make your HTML e-mails look fugly in some web-based e-mail clients. Use something like <b style="font-size:12px; color:#f00">. - Stick to basic HTML tags and style with inline CSS. Sort of an extension of #2. Instead of <h1> , use <b> and style with CSS to your liking. Don't leave it up to e-mail clients to decide what an H1 should look like! Instead of <ul>, use • .
- Put the width and height on everything you can. This includes images, HTML table cells, etc. Don't leave it up to e-mail clients to lay stuff out for you.
If you enjoyed this article, you might consider subscribing to our rss feed to stay updated with all the latest tips and articles!
Article Sponsored by:
Keep up with all of our latest news, articles, and tutorials by following us on Twitter!









This is great, thanks
But a question….
do i just pass the vars to the function when i setup my own php script? thanks to you again!
Yea… just pass the to as an e-mail address, the subject, and the body with the HTML you want to show up in the e-mail
I just lol’ed at the use of the word ‘fugly’ in the article, awesome
This is a great little script Brian, I’m certainly saving it. Do you mind if myself or others use it in clients projects in the future?
No problem at all! Use it up
Thanks. I was searching for this nly
Beautiful! Just what I needed. Thanks, Brian!
If you need a bit more capability than this script provides, check out the Swift Mailer package:
http://www.swiftmailer.org/
Swift Mailer doesn’t do anything that other various PHP functions can’t do without the package, but the Mailer package does provide an object-oriented solution to sending mail and makes more difficult things (e.g., sending attachments) a lot easier than they would be otherwise.
Great function, but I get a called to undefined function error re: br2nl().
I assume this function is converting breaks to new lines, but the function isn’t defined anywhere.
Great spot! Corrected the function. Rock on!
I tend to go for 600px as a maximum width for HTML emails – I may be wrong but I think that’s the default width of the reading pane in some email clients
Good tip!
Hey,
Nice Tutorial Guys.
Just thinking it might be nice to include a demo or maybe even a screenshot of the output of the form!
But apart from that, nice tip
~ Andrew
is it able to send a lot (~200) mails at once? Or is there any restriction from the server?
Or send a newsletter with BCCs only?
thanks for the great function!
hamlet
Very nice function… simple and effective… I was wondering if the function can handle a lot of recipients (ad Hamlet asked)… I ‘ll give it a try soon
This function will send to more than one recipient if the variable $to is a comma-separated list of e-mail addresses, such as foo@bar.com, bar@foo.com
To CC, you will need to add a CC: header to the $headers variable. Messing with with the $header var is a little more advanced and you should look into e-mail headers before messing with it.
Having said all that, your ability to send mass e-mails may be limited by your host to prevent black-listing from recipient servers. For example, Media Temple prevents more than 100 e-mails an hour. Check with your host to see if they have a limit on outgoing e-mails.
Thanks for the script. When I try this script, initially I get, from not in headers. Then, I hardcoded a from in the header and it still did not work. Any ideas?
Hey Mattie,
Be sure to turn on full error reporting and let us know what exactly you are getting and/or a pastie code would help as well
You can also try this PHP mail library:
mMail PHP Class
It’s free and, also doesn’t depend on the built in mail function, which means it can generate messages even in cases where sendmail is unavailable or the SMTP server requires authentication.
very nice …..
http://www.zamshed.info/tech/
Bonus that really is insightful, for this post.
this works great from windows but when I copy it up to my linux server (centos 5, postfix), the messages don’t come out properly.
Any idea why?
Removing these lines:
$headers .= “\nMessage-ID: \n”;
11. $headers .= “X-Mailer: PHP ” . phpversion() . “\n”;
seems to have solved my linux problem.
I don’t get it. Can you help out some noobs on how to implement this code serverside?
Yes HTML mails are prettier. I am not over 80 and I don’t use AOL2.5 Personally I prefer plain text so the message is not obscured and for security reasons. But I know they convert better. and it’s not about me.
Does anyone know any websites that sell nicely designed html email templates? (can’t see any on themeforest)
Harold – ThemeForest will be launching an email templates category very soon, so you’re in luck!
I prefer to receive text only emails. Your derisive condescension is offensive and for someone who provides a service, not a strong recommendation. BTW, my email client has no trouble displaying active links in plain text format emails. Some clients will display photo attachments inline.
I’ve recently started a blog, the information you provide on this site has helped me tremendously. Thank you for all of your time & work.