PHP Send HTML Email

GeekThis happily runs on Vultr. Get $300 of free hosting credits to try out their cloud compute, kubernetes engine, or managed databases. Try Vultr today to claim your free $300.

With the PHP mail function you can send all sorts of emails, including HTML emails and emails that have various attachments. But you will have to generate the proper headers and change the message text. The way the mail function in PHP works, is sending “plain text” emails. HTML emails are plain text emails but with additional headers and the proper encoding set. Below I will show you how you can simply send your HTML emails using PHP without using huge libraries that a lot of people will suggest.

For sending HTML emails, you will have to set two specific headers to begin with. These are separated by a carriage return and line break (\r\n) or CRLF. I set up these headers in an array and then implode them at the end for easy reading and modification.

$headers = array(
	'MIME-Version: 1.0',
	'From: no-reply@localhost',
	"Content-Type: multipart/alternative; boundary={$boundary}"
);

The Content-Type setting allows us to split our content using a boundary that we will specify before the headers variable. With multipart content type, we are allowed to send plain text and html emails together, so if a email client doesn’t support one, the other will still be shown. The MIME-Version is used to specify which internet standard to use when parsing the email. If not set to 1, the email will not be displayed properly.

To generate the boundary variable, I use a simple hash to the current time. You can have your boundary be the same for all emails, and use any method you want. But I have seen a lot of companies use hashing of epoch time.

$boundary = md5(time());

The last part is to generate the message text and send it. When creating your message, make sure you include both text and html versions. You split each part of the message using your boundary so the clients can tell which part to show to the user. Each boundary has to be prepended with two dashes and then ends with a CRLF. At the end of the full message, you have to have your boundary with two dashes appened to the string as well. I setup the message the same way as the header, as an array. Viewing it is much easier than a string of a ton of variables and line breaks.

$message = array(
	"--{$boundary}",
	'Content-Type: text/plain; charset=ISO-8859-1',
	false,
	'This is the plain text message that you are going to be sending',
	false,
	"--{$boundary}",
	'Content-Type: text/html; charset=ISO-8859-1',
	false,
	'<h1>This Is the HTML Email</h1><h2 style="color:red;">And some extra text</h2><p>to show off that this is really html</p><img src="https://www.google.com/images/srpr/logo11w.png" />',
	false,
	"--{$boundary}--"
);

The last thing is to implode all of the arrays and send the message using the default PHP mail function. This function will not work on localhost’s unless you have properly setup your configuration files and your ISP allows for SMTP messages. I suggest trying this from your hosting account instead of localhost. Below is going to be the full code including the mail function.

<?php
	$send_to = 'me@localhost'; // Who to send the message to
	$subject = 'Test Message'; // Subject

	$boundary = md5(time());

	$headers = array(
		'MIME-Version: 1.0',
		'From: no-reply@localhost',
		"Content-Type: multipart/alternative; boundary={$boundary}"
	);
	$message = array(
		"--{$boundary}",
		'Content-Type: text/plain; charset=ISO-8859-1',
		false,
		'This is the plain text message that you are going to be sending',
		false,
		"--{$boundary}",
		'Content-Type: text/html; charset=ISO-8859-1',
		false,
		'<h1>This Is the HTML Email</h1><h2 style="color:red;">And some extra text</h2><p>to show off that this is really html</p><img src="https://www.google.com/images/srpr/logo11w.png" />',
		false,
		"--{$boundary}--"
	);

	mail($send_to,$subject,implode("\r\n",$message),implode("\r\n",$headers));
?>

If you would like to see how the Plain Text email looks in Gmail, since there isn’t any visible option to do so. Click the drop down array next to the reply button (top right of the message). Find the link to “Message Text Garbled.” This will show you the plain text message.

If the message does not get sent, check your PHP error logs along with your servers SMTP logs. My server doesn’t allow for messages from anyone other than the domains hosted on the server. I would suggest trying a no-reply@yourdomain for the From variable in the headers if you are not getting your messages.

Related Posts

PHP - Check if Production or Sandbox

Use PHP to check of your site is on your development server or uploaded to the production server.

Setup PHP Development Web Server Quickly inside of Windows

Quickly setup a PHP development enviornment by using the built in PHP web server with no additional software required.

PHP Dynamic Subdomains

How to setup dynamic subdomains with PHP to give users a custom domain for their profile page.

Parsing AWStats with PHP

Parse Awstat files using PHP including information about the awstats file format.