Many PHP websites and web applications need to send transactional emails. A user may request a password reset that sends them an email, or you may need to notify a customer that their order has shipped. PHP does have a mail() function you could use to send an email from the web server itself, but there are some drawbacks to doing this. Instead, I recommend using an external mail server to handle these emails.

Delivering automated emails reliably can be very difficult. Email providers and internet service providers (ISPs) take spam very seriously. A study last year found that 19% of all permission-based email goes undelivered. Some of that undelivered email (7% of the total) gets sent to the recipient’s Spam folder, but even more than that (12% of the total) simply goes missing — silently blocked by the ISP before it reaches the intended recipient.

Email providers and ISPs take a number of factors into account when deciding whether or not to deliver a message. The reputation of the server sending the message is one of these factors. If your site runs on shared hosting, you share that reputation with every other website on that server. If any one of those sites gets identified as a spammer, the whole server can get blacklisted: any email sent from the server (including from your website) could go undelivered. You want your emails sent from a server with a really good reputation.

As your website increases in traffic, you will probably switch off shared hosting and scale out to use multiple web servers to handle the load. If you keep the servers that generate web pages separate from the servers that send emails, you’ll be able to scale them independently. It’s easier to manage your infrastructure when functions like these are de-coupled from each other.

You could host your own mail server, but I would recommend using a service like Postmark or SendGrid to handle sending these emails. The prices for these services are incredibly low for small levels of activity: Postmark lets you send 1,000 emails for free and then charges you only $1.50 for each batch of 1,000 emails after that. If you send a lot of transactional email (I mean, a lot), it might be cheaper to host your own mail server — but I would think it would take a significant cost-savings to make it worth the headache of managing it yourself.

The time not spent dealing with email problems is worth the price of Postmark many times over. Chris Dary, CTO at Readability

Whether you host your own separate server or use a third-party service, Simple Mail Transfer Protocol (SMTP) is the easiest method to have your web server interact with an email server. Most of the third-party services have their own unique APIs, but they typically support SMTP. I would recommend using SMTP at least until you find a service that you love. After that, you might want to integrate with them more tightly through an API to take advantage of some more advanced features — or you may want to keep using SMTP to make it easier to switch to a different service in the future.

To use SMTP in your PHP code, I recommend using PHPMailer. This third-party library provides the settings and functions you need to send email using a variety of methods, including SMTP. You can find an SMTP example in the test_smtp_basic.php file in the examples folder of the library.

First, place the two necessary files on your server:

  • class.phpmailer.php
  • class.smtp.php

Then, include the library and instantiate a PHPMailer object:

require_once('path/to/library/class.phpmailer.php');
$mail = new PHPMailer();

Next, set up the object to use SMTP and configure it to point to the proper server; I’m using Postmark in this example:

$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->Host = "smtp.postmarkapp.com";
$mail->Port = 26;
$mail->Username = "#@#@#@#@-####-@@@@-#####-@#@#@#@#@#@#";
$mail->Password = "#@#@#@#@-####-@@@@-#####-@#@#@#@#@#@#";

Finally, set the properties for the particular email you want to send:

$mail->SetFrom('name@yourdomain.com', 'Web App');
$mail->Subject = "A Transactional Email From Web App";
$mail->MsgHTML($body);
$mail->AddAddress($address, $name);

Once everything is set up the way you want it, you call the object’s Send method. If the Send method returns true, then everything worked. If it returns false, then there was a problem.

if($mail->Send()) {
  echo "Message sent!";
} else {
  echo "Mailer Error: " . $mail->ErrorInfo;
}

Note About Form Submissions

Many sites have forms that send email to the site owner, such as a contact form. You can use the technique described above for sending these emails, but there is one thing to note. You usually want the “From” address on the email to be the email address of the person completing the form; that way, you can simply reply to the email to send them back a response. With many of these third-party services, however, you may notice that the “From” address gets changed from the email address you specify to the email address associated with your account.

This behavior will vary by provider. Postmark, for example, will replace the “From” address when you send through SMTP. (They leave it unchanged if you use their API.) This helps your emails get delivered, but it can make it a little inconvenient to reply. You’ll want to be sure to include the email address in the body of the email so you can copy it and paste it into the “To” field when you reply.