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.
Any idea, why i dont receive anyy emails even if there is no errors on SMTP connection using postmarkapp.? It’s little bit urgent. So any help is greatly appreciated.
Hi
why when i am sending email using PHPMailer its going to spam folder
please help me
How do I force the PHP mailer to use our domain email instead of GMail?
I’m trying to send email using phpmailer using SMTP.gmail. com, but I got the SMTP error: called mail() without being connected. Can you help me to solve this error
hi,
I’ve been using your code and it kind of does the job, meaning that I receive an email whenever I click the submit button….the question I have is how can I include the contact form in the email too?
Thanks yourexplaination saved me a bit but I keep getting the logs of how the smtp works like
SERVER -> CLIENT: 220 smtp.gmail.com ESMTP w79sm1014987wme.19 – gsmtp
CLIENT -> SERVER: EHLO localhost
SERVER -> CLIENT: 250-smtp.gmail.com at your service, [197.210.227.25]250-SIZE 35882577250-8BITMIME250-STARTTLS250-ENHANCEDSTATUSCODES250-PIPELINING250-CHUNKING250 SMTPUTF8
please how do i disable this (using wamp server)
Hi Tobi! As this is an older post, we’d recommend asking your question in the Treehouse Community where teachers and students are always happy to help.
I have facing the same issue, Can you help me to hide the log,
Thanks
Hi,
What would be used for the username and password fields? when using postmark?
Thanks,
James.
Hey, I know this is an old post, but I’m having problems with getting an email to send through PHPMailer in that when the email arrives, the body of the text is actually an attachment?
Could this be through a setting in the PHPMailer script or does it sound like something more server based?
Any help you might be able to give would be appreciated.
I don’t know why $email->IsSMTP(); does’nt work on my server. I use PHP mailer-FE v4.11
In the class.phpmailer.php file look at this line;
public $Mailer = ‘smtp’;
If this is set you don’t need to have $email->IsSMTP(); in your code.
I have tried this code but it is giving this error “Called Mail() without being connected” Kindly guide me to resolve it
Hi Randy,
Currently emails submitted via my drupal based website aren’t coming through to my exchange server. I have checked and there are no firewall blocks and the emails are’nt stock in the exchange que. Is it possible that the ISP is blocking the emails as spam?
Thanks for your useful tutorial. I was serving this for last two weeks. You provide good guidelines.
sir ,
this code is not working in php vertion 4 ..
please help sir
Thanks Randy, works like a charm.
Thanks Randy!!
really ..nice…..
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.
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”.
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!
hi how to send email using Gmail smtp … .
You can use Gmail’s SMTP details, which are usually
$mail->Host = “smtp.gmail.com”;
$mail->Port = 587;
$mail->Username = “youremailaddress@gmail.com”;
$mail->Password = “yourgmailpassword”;
But be warned that Gmail tries to “prevent” sign-in attempts “from an app that doesn’t meet modern security standards”. So it might not work.
Also, with services like SendGrid, Postmark or Mandrill, you get stats about your email delivery, like telling your if the email was opened, if it was bounced, if someone clicked on a link in the email and much more. Gmail doesn’t provide you these stats.
Hope that helps. Cheers
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.
+1