Sending Email With PHPMailer and SMTP

php

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.

Randy Hoyt

Randy Hoyt is on the Teaching team at Treehouse. He's been building web sites and web applications for years, and you'll often find him speaking about his experience at local events and conferences. He spends whatever time he can find offline studying mythology and playing board games. Twitter: @randyhoyt

Comments

10 comments on “Sending Email With PHPMailer and SMTP

  1. The link to this article appears to be missing from your Programming > Build a Simple PHP Application > Wrapping Up The Project > Deploying The Site page.

  2. Maaan!! You saved my asss!! Thanks sooo much!!
    I couldnt use pear bc of some random stupidity with my host but followed your tuto and worked 100%
    Thanks man!

  3. I tried this but I keep getting a message saying that there was a problem sending the email because the email address failed. Could anyone help me with the ideas of what I did wrong?

    • I’m trying to use smtp.gmail.com and get the same thing. It works from my local machine, but when I upload to my server i get the same message as you. Also it says, “Called Mail() without being connected”.

  4. Hey Randy, truly appreciate the article. I understand that this article has been posted awhile but I hope this question doesn’t cause an inconvenience. I have used phpMailer once and at this time I noticed that it takes approximately 5 – 26 secs to process the mail to be sent and bring back the screen. Is there any other reasons besides the server that could account for this time? Do you have any suggestions as to how to make the mail send faster through phpMailer. Thanks. Awaiting your response.