Sending e-mails via SMTP with PHPMailer and Gmail

These days I tried some PHP scripts to send the e-mail messages for my contact form via SMTP. Since my domain’s email is hosted with Google Workspace I decided to send the messages via the SMTP server from GMail. I found several articles and PHPMailer tutorials, but a lot of them didn’t worked for me.

Why using GMail for sending mail messages?

First of all it’s FREE! Sure most website owners can use their own SMTP server for sending email messages from their website, but it makes sense even than to use GMail for sending mail. The chance is big that your websites IP address is on a blacklist if your site is on hosted by a shared web hosting provider. If not or you host your site on your own server, there is always a risk that your IP address get blacklisted. Because of some limitations, the SMTP server from Google is a good choice for applications with less than 500 recipients a day, check this information from the Google help pages.

Requirements

You need for this PHPMailer code example a PHP enabled web host (I did tests only on Linux), the port 465 need to be open and of course you need a GMail or Google Workspace account.

Trouble sending e-mails with your “normal” GMail account? If you own a domain name, you can register for a Google Workspace account or check below the tutorial update about an alternative SMTP service!

PHPMailer tutorial for Google Workspace (or GMail)

  1. If you don’t have one, register a GMail account or setup your domain for Google Workspace.
  2. Download a recent version of PHPMailer (I’m using the version 5.02)
  3. Check that your web hosting provider has opened the port 465 (TCP out), if not ask him to open that port
  4. Include the PHPMailer class file: require_once('phpmailer/class.phpmailer.php');
  5. Create those two constant variables to store your GMail login and password. Use the login for your Google Workspace mail account if you have one.
    define('GUSER', 'you@gmail.com'); // GMail username
    define('GPWD', 'password'); // GMail password
    
  6. Use the following function to send the e-mail messages (add the function in one of your included files):
    function smtpmailer($to, $from, $from_name, $subject, $body) { 
    	global $error;
    	$mail = new PHPMailer();  // create a new object
    	$mail->IsSMTP(); // enable SMTP
    	$mail->SMTPDebug = 0;  // debugging: 1 = errors and messages, 2 = messages only
    	$mail->SMTPAuth = true;  // authentication enabled
    	$mail->SMTPSecure = 'ssl'; // secure transfer enabled REQUIRED for GMail
    	$mail->Host = 'smtp.gmail.com';
    	$mail->Port = 465; 
    	$mail->Username = GUSER;  
    	$mail->Password = GPWD;           
    	$mail->SetFrom($from, $from_name);
    	$mail->Subject = $subject;
    	$mail->Body = $body;
    	$mail->AddAddress($to);
    	if(!$mail->Send()) {
    		$error = 'Mail error: '.$mail->ErrorInfo; 
    		return false;
    	} else {
    		$error = 'Message sent!';
    		return true;
    	}
    }
    

    Most of the settings inside the function are required by GMail. While searching for PHPmailer tutorials I found articles with different settings for the port and security. My advice is to use the settings from this tutorial.

  7. Call the function within your code:
    smtpmailer('to@mail.com', 'from@mail.com', 'yourName', 'test mail message', 'Hello World!');
    

    Use this more “advanced” usage inside your application:

    if (smtpmailer('to@mail.com', 'from@mail.com', 'yourName', 'test mail message', 'Hello World!')) {
    	// do something
    }
    if (!empty($error)) echo $error;
    

Advanced setup with fall-back SMTP server

Because of the e-mail message limit it might be useful to use a secondary SMTP server if the GMail option is unable to send the message. For this functionality you need to replace the part with the SMTP settings. First create login/server variables for the second SMTP server:

define('SMTPUSER', 'you@yoursmtp.com'); // sec. smtp username
define('SMTPPWD', 'password'); // sec. password
define('SMTPSERVER', 'smtp.yoursmtp.com'); // sec. smtp server

Next we need to create an if/else statement using the variables for the second server (replace).

 
function smtpmailer($to, $from, $from_name, $subject, $body, $is_gmail = true) { 
	global $error;
	$mail = new PHPMailer();
	$mail->IsSMTP();
	$mail->SMTPAuth = true; 
	if ($is_gmail) {
		$mail->SMTPSecure = 'ssl'; 
		$mail->Host = 'smtp.gmail.com';
		$mail->Port = 465;  
		$mail->Username = GUSER;  
		$mail->Password = GPWD;   
	} else {
		$mail->Host = SMTPSERVER;
		$mail->Username = SMTPUSER;  
		$mail->Password = SMTPPWD;
	}        
	$mail->SetFrom($from, $from_name);
	$mail->Subject = $subject;
	$mail->Body = $body;
	$mail->AddAddress($to);
	if(!$mail->Send()) {
		$error = 'Mail error: '.$mail->ErrorInfo;
		return false;
	} else {
		$error = 'Message sent!';
		return true;
	}
}

And next use the modified PHPMailer function as followed:

 
$msg = 'Hello World';
$subj = 'test mail message';
$to = 'to@mail.com';
$from = 'from@mail.com';
$name = 'yourName';

if (smtpmailer($to, $from, $name, $subj, $msg)) {
	echo 'Yippie, message send via Gmail';
} else {
	if (!smtpmailer($to, $from, $name, $subj, $msg, false)) {
		if (!empty($error)) echo $error;
	} else {
		echo 'Yep, the message is send (after doing some hard work)';
	}
}

Both examples are very simple and demonstrate only how-to send e-mail messages using PHPmailer with the SMTP server provided by GMail. Of course you can extend the code to handle HTML messages and attachments etc. If you have any issues with these examples, just let me know.

UPDATE: Alternate SMTP service

Since this tutorial was published, I got several messages that the free GMail account doesn’t allow you to send a lot of e-mail messages from your own websites. Your can use this PHPmailer example code for any other SMTP server or service. I suggest to use ElasticEmail, a premium e-mail service provider in the cloud. Signup for a free account which is good for the first 25.000 mail messages and 10.000 contacts every month.

If you use the tutorial code with ElasticEmail you need to replace this part of code

	if ($is_gmail) {
		$mail->SMTPSecure = 'ssl'; 
		$mail->Host = 'smtp.gmail.com';
		$mail->Port = 465;  
		$mail->Username = GUSER;  
		$mail->Password = GPWD;   
	} else {
		$mail->Host = SMTPSERVER;
		$mail->Username = SMTPUSER;  
		$mail->Password = SMTPPWD;
	} 

with this code

	$mail->Host = 'smtp.elasticemail.com';
	$mail->Port = 2525; 
	$mail->Username = 'your username';
	$mail->Password = 'your password';  

Optional: Remove the “$is_gmail” attribute from the function.

Published in: PHP Scripts

87 Comments

  1. very nice post, thanks.

    I havent tried it with goolge but you might want to have a look at zend framework mail classes. They have very nice api and a lot of functionality. To be honest i prefere to stick with zend as long as fulfills my needs ;-)

    Thanks

  2. Hi Artur,

    you’re right I like the Zend Framework too.
    Never user the mail class from them because I like phpmailer a lot. If you start a small website it’s much faster to use phpmailer. Do you have any experience about the “reach the inbox success” for the Zend SMTP mail class?

  3. Just noticed that I forgot to use the Cc option inside the function. I removed it from the example

    (this information is for people read the tutorial within the last 12 hours)

  4. You have misstype in requirements,
    port 465 it is Gmail server port and PHPMailer don’t need to open it on your server. You have set it as server settings in you class configuration.

    So you need to verify possibility connections to this port on another server, not your server port.

    PS:
    port 465 is SMTPs port – secure SMTP

  5. Hi Alexandr,

    that’s right port 465 is needed by Gmail’s SMTP server. In my example script this port is only used for that server. The fall-back example is using the default SMTP Port: 25.

    The requirements are related to sending mails via Gmail’s SMTP server.

  6. Really cool tutorial. The best way to get into the inbox is not send mail from your own server, and let someone else deal with it.

    That said, there are plenty of other factors that will will put your email in the spam folder. Reverse PTR, SPF Records, Domain Keys, and various mail headers are things that will still need to be set correctly for your email to make it to the Inbox.

  7. I suggest the function could return true in case of succcess, and the error message in case the email is not sent, so not global variable is used, and the outside code would be something like

    if (($error = smtpmailer($to, $from, $name, $subj, $msg, false)) === true)
    {
    // Everything went fine
    }
    else
    {
    echo $error;
    }

  8. Sorry Olaf and lloyd27 my php isn’t fluent. Am I missing something? How is lloyd27’s call to the function attempting to send via gmail? He’s set the parameter $is_gmail to false.

  9. Hi Jeff,

    lloyd27’s snippet is just to demonstrate the error handling, it’s not related to the mail function in this tutorial.

    The code like described works very well.

  10. Hi,

    Excellent article. I am often having problems with my shared host being blacklisted through genuine email distribution scripts on the accounts within it and this script looks like an excellent way around that.

    Of interest, http://mxtoolbox.com/blacklists.aspx is a good resource for checking blacklist status if you’re having trouble sending, as I was.

    Regards,

    David McLeary
    Emerging Innovations

  11. For GMAIl:

    On my server the SSL port was blocked. If so, try using the TLS (587) port. On other webmail sites you can try to use that port too.
    BTW, you Gmail account can get blocked if you’re not using this script the right way: then you have to use e-mail verification to be able to use your gmail account again.

    1. You can replace the WP mail functions using SMTP only, search for the SMTP mail plugin and use your gmail settings for the SMTP mail transport. I remember me that there are WP contact form plugins available providing SMTP features too.

  12. Do you tried the smtp settings with a regular mail client first? Check also with your hosting provider that these ports are open.

  13. Can anybody send me all contact form file, actually i don,t know about php and i have to make a contact form.

    thanx

    1. I don’t think that a custom php contact form will work for you. You need always some basic knowledge to build a contact for a website.

      You need to know how a posted form works

      basic understanding how a mail script in php works

      and finally you need to know ho to use (form) variables

      This tutorial is actually a beginners tutorial, just give it a try. In my experience most problems people have using the script in this tutorial are NOT related to PHP ;)

  14. I really appreciate your method of code (as you mentioned fall-back method, incase google-mail fails).

    Great tutorial.

  15. I’ve got this all set up just like above but it keeps giving me:
    Mailer Error: The following From address failed: mail@example.com
    I’ve tried getting it to send all emails from the gmail address too but it makes no difference. Please help :(
    Andy

  16. Hello Andy,

    first you can try to get some more debugging information while setting this property: $mail->SMTPDebug = 1

  17. Problem solved.

    I decided to take a look at the documentation again, see what I was missing. See my old server didn’t use SSL but I no longer have access to it so switched to Gmail using the tutorial here to edit the code I already had.

    After a quick look at the documentation I discovered that there was no such variable as SMTPSecure… I didn’t check something really obvious, as you say in step 2:

    “Download a RECENT version of PHPMailer.” I was using v1.2, LMAO XD

    Thanks for your help Olaf :)

  18. This is exactly what i needed. I toyed with google Xoauth for SMTP mails on my site, but all I got was port errors and Zend errors for the past two days. Now this works like a charm. I have a question, though. Can users who come to my site login using their gmail username and password on my website, and send emails without leaving the page? Meaning i’m not the one sending the message, they are, but the request to google comes from my website. you reply appreciated, thanks.

  19. hi
    i get this error :

    sockopen() [function.fsockopen]: unable to connect to ssl://smtp.gmail.com:465 (Unable to find the socket transport “ssl” – did you forget to enable it when you configured PHP?)

    how do i configure php for ssl?

    best regards

    1. Hi Ron, ask your hosting provider or maybe you need to do this by yourself (if this server is your own one). Note, compiling software for web server is not a basic task.

  20. Hi,

    I also get this error.

    sockopen() [function.fsockopen]: unable to connect to ssl://smtp.gmail.com:465 (Unable to find the socket transport “ssl” – did you forget to enable it when you configured PHP?)

    I not using web hosting yet. I test it with my laptop with apache and php.

    What should i do?

    1. Hi, I guess you’re trying run that script on a windows machine right? OpenSSL is a standard on Linux but not for windows, check google for “openssl for windows”

  21. Great information. Has anyone had issues with trying to send larger quantities (say 200) emails through Gmail’s SMTP server and having it only send 5 or 10 and then display errors for “Daily sending quota exceeded”?

    I’m using a newly created gmail account and have only sent a couple test emails before trying with the php script, so I know it shouldn’t be exceeding the limit. Not sure what else to try at this point, and forget about trying to contact Gmail support to ask.

    Thanks.

  22. Hello Jim,

    according the Google website it’s okay to send 500 messages a day (to diff. e-mail addresses). I think that many people getting this limit warning because the send them to fast. Try the script from this site and send not more than one mail message every 5 seconds.

  23. Thanks so much for the reply. I’m amazed that I’m not able to find more posted online about this. I’ve done more testing and I think you’ve solved part of the problem with the delay recommendation. After I set it to a 3 second delay between emails I was able to send 350 emails with no errors. This was done using my Gmail account with my own domain name.

    However, when I tried this morning with a newly created basic/free gmail account with the gmail domain, it only allows me to send 23 out of 100 emails. The rest show “over quota” errors. I’m seeing the same thing with two customers who have regular gmail accounts and it won’t send but 5 to 10 of their emails.

    So it appears that there is a separate quota for gmail accounts if you have your own business account using your domain or if you use the basic @gmail.com address… and I’ve found nothing on google’s site that states this. Everything I’ve seen says 500 emails through SMTP per day.

    1. I never tried to use Gmail’s SMTP server within a web application. Do you try to send a kind of newsletter? In this case a mailing list provider can help. Mailchimp offers a great free version.

  24. Actually it’s a feature of a website service I have for some teachers. They maintain an address book and can send emails to their students. I’m tired of dealing with the hosting company’s mail server getting blocked, so figured Gmail would be a better option. Just not sure how to get past this reduced quota issue.

    1. Hi Jim,
      okay I see, in that case you have a small budget right? I got a a (free) SendGrid account because I hired a server from Rackspace, their service looks really good, is easy to use and you get a plan from $9.95 / month. (cool two affiliate links in the same post, lol)

  25. Thanks. I had thought about a service like that but the only problem is I have it so my customers can send email from an email account they own as the From address. I can’t tell from the SendGrid site if that’s possible, but I would guess that it’s not and you can only send from your main domain email you’ve setup with them. Do you know if that’s the case?

    1. I know that there are several options, one of them is a feature to use their SMTP service for your gmail account :D
      Try them…

  26. Which phpmailer did you use, i got this error
    Fatal error: Call to undefined method PHPMailer::SetFrom() in /home/

    I could not find SetFrom in the class….

    Can u help ?

  27. Thanks,

    It can run on localhost ?

    now I’m using the PHPMailer with XAMPP.

    PHP version is 5.3.1.

    and PHPMailer show me this message ‘Invalid address: SMTP Error: Could not connect to SMTP host.’

    F1…Me

  28. Hello ZTH, it should work local.

    I remember me that the SMTP setup on windows was always some trouble, but is should work if you open the right ports and you’re using google as SMTP host

  29. I like it a great tutorial I have on quick question? You said the following before you showed how to layout the function: Use the following function to send mail messages (add the function in one of your included files): by included files do you mean create a separate file to hold this function and is there anywhere I could see this program out laid out? Thank you

  30. great work Olaf,
    i want to ask how to configure wamp for phpmailer to work. because i get this error

    Failed to connect to server: Unable to find the socket transport “ssl” – did you forget to enable it when you configured PHP? (74209264)
    SMTP Error: Could not connect to SMTP host.

    Can u plz help me… it has been three days since am stuck in this…

    thanks

    1. Hi Hunain,

      I think your problem is related to “Windows”, SSL is not installed by default on windows machines.
      Try the SMTP service provided by SendGrid (instead of Gmail)

  31. Thanks a lot for this post. It’s been very helpful. One suggestion for the sending limit is to upgrade for Google Apps (the free version). The limits for that are outlined here: https://www.google.com/support/a/bin/answer.py?hl=en&answer=166852

    You’ll notice on the bottom this line of text:
    If you have a local mail server, connect to Google Apps mail servers using SMTP or SSL; the sending limits do not apply in this configuration.

    Perfect for my use =)

    1. Hello Steve,
      thanks for the link, I noticed this kind of information before but this page answers a lot of questions. I used my Google Apps account while testing the code and never had a problem with the script and the Google mail servers.

  32. im having a problem that i have install wamp server 2.1 and i want to send from this install computer to my gmail. i dont install any mail server or anything other than wamp server 2.1 and internet.
    please help, what are the suitable way to process this,

    1. Hello,
      this code works for every PHP installation, because you’re using the PHPmailer class for the e-mail transport. The external SMTP server is used instead of a local mail server.

      Maybe you need to open some ports in your firewall.

  33. when i process this a error occur saying “Fatal error: Class ‘PHPMailer’ not found in C:\wamp\www\praveen pro\sms.php on line 9” means they not found this class in php

  34. hi! this is a great tutorial :) however i get this error message under Windows: SMTP Error: Could not connect to SMTP host. Mail error: SMTP Error: Could not connect to SMTP host.
    But it works fine with Ubuntu. Any help on how i could fix it? Thanks :)

  35. I’m able to send mail fine, but it seems SetFrom() is not working. It is always using my gmail username email address as the return path / reply to, though it uses the correct from name.
    Are you able to get the from : email overridden? I need our users to be able to send us emails and have the return path be correct.

  36. Okay, it seems the reply-to is getting set correctly. I suppose the From email address setting is a Google security feature.

    1. Hello Tor,
      Yes it’s a requirement for many SMTP services. The “reply-to” option is okay for most e-mail clients except Gmail :(

  37. when i connected with above code in php i am getting this error:
    Warning: fsockopen() [function.fsockopen]: unable to connect to smtp.elasticemail.com:2525 (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ) in D:\Hosting\8583370\html\dcpit\edu\class.smtp.php on line 89
    Mailer Error: SMTP Error: could not connect to SMTP host server(s)
    please help me what to do .

    1. Check with your hosting company the following directives : allow url_fopen need to be set, safe_mode most be off and check that open_basedir is okay too.

  38. Hi, I setup everything the same as you did, but i got an error: Mailer Error: Could not instantiate mail function. Do you know why this happen and how to figure it out.

  39. Hello,
    sorry that it took so long until your comment was published.
    Do you tried the debugging function from phpmailer? In most of the cases it’s possible to see where the problem exists. (if you can’t post the output via pastebin.com and post the link here)

  40. In case you run into an error like this: “Call to undefined method PHPMailer::SetFrom()” despite of installing the most recent version (I used v.5.2.1), just use the same version as the author’s (v.5.02) or v.5.01.

    Thank you Olaf and commentators. You saved me from days of agony.

  41. Hi Chris,
    That’s strange, I checked the current version (5.21) and the SetFrom method still exists (check row ~520 from the class.phpmailer.php file).
    But I’m glad that my example was helpful.
    If you run into problems with the sending limit of Gmail, don’t try to fix it and use Sendgrid or some other SMTP provider.

  42. Yeah… Now Gmail doesn’t allow you anymore to do tricks like this with their email service. They realized that a lot of spammers do this and they introduced extra security measures with the HELO relays. Now they allow only FQDNs.

    1. Hi Daniel,
      I know it was always looking for trouble if you try to use your free Gmail acount as the SMTP server for your web application. I used for tests while writing this tutorial my Google Apps account. The best choice is an alternative SMTP service, Sendgrid is cool and offers a free account as well (enough for smaller applications)

  43. Thanks. At last I’m able to send emails from localhost with XAMPP.
    I know the topic is a bit old, but let me add my few cents – for all those, who have trouble with SMTP errors, remember to uncomment the line
    extension=php_openssl.dll
    in php.ini

    1. Hi Chmieloo, thanks for the tip. I know ssl on windows is not really fun :)
      For a development box you can use the free version from Sendgrid as well (works for me)

  44. Hello,
    I tried this but,Getting error —
    SMTP Error: Could not connect to SMTP host.

    Any help can be appreciable..

    IsSMTP(); // enable SMTP
    	$mail->SMTPDebug = 1;  // debugging: 1 = errors and messages, 2 = messages only
    	$mail->SMTPAuth = true;  // authentication enabled
    	$mail->SMTPSecure = 'ssl'; // secure transfer enabled REQUIRED for GMail
    	$mail->Host = 'smtp.gmail.com';
    	$mail->Port = 465; 
    	$mail->Username = GUSER;  
    	$mail->Password = GPWD;           
    	$mail->SetFrom($from, $from_name);
    	$mail->Subject = $subject;
    	$mail->Body = $body;
    	$mail->AddAddress($to);
    	if(!$mail->Send()) {
    		$error = 'Mail error: '.$mail->ErrorInfo; 
    		return false;
    	} else {
    		$error = 'Message sent!';
    		return true;
    	}
    }
    smtpmailer('name@domain.com', 'name@domain.com', 'Name', 'test mail message', 'Hello World!');
    
    
  45. Hello Nazer,

    check the comment from Daniel a few months ago, he told us that GMail doesn’t allow this anymore.
    You need a Google Apps account or beter use some commercial SMTP provider like SendGrid.

  46. HI,
    I am using this code Code and i am using the jango smtp and their recommended settings but still i am getting this error and i am not able to figure out what is going wrong .
    Please help .
    Thanks

    I get this error –

    SMTP -> ERROR: Failed to connect to server: Connection timed out (110)
    The following From address failed: demolition.boys.x@gmail.com : Called Mail() without being connected

    1. Hi Somi,

      do you used exact the same details with your e-mail program (like thunderbird) before? Use the debugging option to see where it breaks.

  47. In point 7. (Call the function within your code), you have passed six arguments to the function. Second one being ‘ ‘. This will be a mismatch from the function signature, as your smtpmailer function accepts only five arguments.

    1. Thanks Zeeshan, the bug is fixed. Strange that no one has reported this bug during the last 2 or 3 years :)

  48. I tried using this and had somewhat success, however after sending an email (which never came through) I got an email from the Google servers themselves saying suspicious account activity had been blocked (Im guessing because I’m in England & my server is US based) Anybody have a way around this?

    1. Hi Devon, do you use a Gmail or Google apps account?
      Like other people told before, a Gmail account doesn’t work anymore for SMTP mail on your website.

  49. Hi, check the article again, you can’t use Google’s SMTP server with a regular Gmail account anymore.

  50. Hi I have a query regarding PHP mailer.
    I developed a form using PHP Mailer.
    I can able to receive email with PDF and Image attachments using PHP Mailer.

    My Question is,
    When we receive the email, Image is shown as a thumbnail in the attachments.
    I need to show PDF files also as a thumbnail. Can we make it look as a thumbnail.

    It would be great if I get a solution for this. Please notify me if question is not clear.

    1. Hi Gunaseelan,
      actually you can’t do this. An e-mail message is very basic and you can’t let them act differently.
      That the image show some thumbnail is the behavior of your e-mail client and not an “e-mail feature”.

  51. You’re welcome Gunaseelan,

    Instead of using attachments you can send out a HTML email with images (previews) which link to the PDF hosted somewhere else (if this is an option)

  52. Just one comment on it…
    Everything is working fine until you have the proper http server installed.
    I mean, I spent lots of hours to find the “error”, why neither tls nor ssl worked for me.
    I use apache 2.2 and php 5.x on my Win7.

    I tried :
    – to uncomment the extension=php_openssl.dll in my php.ini and restart my http server
    – to install opensll
    – to use the tls and ssl in t he sample file
    – … and everything I can get from internet
    But everything was IN VAIN!

    Solution:
    I had to replace my apache http server to a “compiled-with-openssl” distribution.
    It is so obvious. Now. :)

    If nothing helps, try this on Windows 7.

    P.S.:
    In linux I had no problems like this. Yes it is a advertisement.

  53. Hi
    I am learning joomla3.1.5 at this moment.
    I have installed apache2.4 as local server on my laptop(window7)
    I have also installed PHP5.5 and MySQL5.6 on laptop separately .
    The Problem is when I am trying to send mail from my Joomla site(running on local server on
    localhost error comes as:
    (i) Could not instantiate mail function—->when using PHPMail in joomla Server Mail Setting.
    (ii) Could not execute: /var/qmail/bin/sendmail, Email could not be sent—–>When using
    SENDMAIL in Joomla Server Mail Setting.
    Could you help me step wise(as I am new).
    Thanks
    Regards
    Jai

Comments are closed.