Do you need to send emails from your PHP application?
This complete guide will teach you how to setup and run the most used PHP email library: PHPMailer.
Learning how to send emails will take your PHP code to the next level. You will be able to write an alert daemon, receive an email when someone tries to log in and much more.
This tutorial covers all you need to know: the installation steps, the class functions, how to use SMTP authentication (including Gmail), how to handle errors and more. You will also find many code examples.
(You probably want to add this page to your Bookmarks to come back here for reference.)
Table of contents
- why use PHPMailer instead of mail() or other libraries?
- how to install PHPMailer on Windows and Linux (updated in 2018, with and without Composer)
- how to send your first email
- how to use the PHPMailer class
- how to use a custom SMTP server
- debugging and error handling
- how to use PHPMailer with Google (Gmail) SMTP
- conclusion

WHY USE PHPMAILER?
PHPMailer offers many functionalities over the PHP core function mail(), including SMTP SSL encryption and authentication, HTML messages, file attachments and more.
On top of that, PHPMailer is much easier to use than mail() and provides a clean, readable object-oriented syntax.
Let’s see in more detail why you should use PHPMailer instead of mail() or other third-party libraries.
WHY USE PHPMAILER INSTEAD OF mail()?
For at least two good reasons.
The first is that mail() relies on the server email subsystem to work. This means that if you want to change some settings like the SMTP server or the authentication parameters, you need to do it system wide.
That is usually a quite difficult operation, and unless you have a dedicated server or you are using a local PHP development environment, you are probably not even allowed to do it.
This also makes almost impossible to use different configurations at the same time, for example using multiple SMTP accounts and switching between them programmatically.
As you will see in a minute, with PHPMailer is very easy to change any parameter dynamically right in your PHP script.
The second reason is that mail() doesn’t offer any advanced functionality.
mail() is fine for sending simple, plain text emails, but it’s very limiting if you need to do anything more than that. Adding attachments or sending HTML emails, for example, is very difficult with mail(), while with PHPMailer it’s just a matter of a single line of code.

ARE THERE PHPMAILER ALTERNATIVES?
Yes, there are other libraries like Zend Mail, SwiftMailer and Zeta Components Mail, but PHPMailer is usually the first choice because of its popularity.
Of course, if you are already familiar with another mail extension and it works fine for you, you can just stick with it.
But if you want to start using one of them and you need to choose which one to go with, PHPMailer is probably the best choice because it’s the most used one.
Other extensions like Zend Mail, SwiftMailer or Zeta Components Mail are probably as good as PHPMailer, but look at the Google search results for “php mail library”:

And these are the results on YouTube:

As you can clearly see, PHPMailer dominates the first results. That doesn’t necessarily mean PHPMailer is better than other extensions, but it does mean it’s the most popular.
The main reason you want to go with the most used library is support: the more widely used a piece of software is, the easier is to find help and examples online.
I should also mention that I have been using PHPMailer for work for a few years now, sending up to 100 emails per day with it. I use it to send alerts using PHP daemons, to monitor my scripts’ memory usage and to receive warnings if SQL injection attacks are detected.
As far as I remember, I never had any trouble with it, so chances are you won’t either.
If you want to learn more about how to use the PHP mail() function, the Pear Mail extension or Swift Mailer, you can take a look at this detailed tutorial from Mailtrap.
HOW TO INSTALL PHPMAILER? (UPDATED IN 2018)
Older versions of PHPMailer (up to version 5) used to provide a “PHPMailerAutoload.php” file, and all you needed to do was to include it in your script.
Starting from version 6, however, this file is no longer provided. Now, to make the PHPMailer class available in your script you have two options:
- use Composer to download PHPMailer and automatically create an autoloader file;
- manually download the PHPMailer source code and include the required files yourself.
The first option is the recommended one, because Composer takes care of all the download, update and dependency check steps. This is especially useful if you need to install other libraries as well, like the one needed for XOAUTH2 Google authentication (I will tell you how to use XOAUTH2 with Google later in this post).
However, the second option may be useful if you don’t want to install Composer for some reason, for example if you are using PHPMailer on a testing environment.
Let’s see both installation options, starting with the one with Composer.
Installing Composer and PHPMailer on Windows (if you use XAMPP, WAMP etc.)
Composer is a dependency manager for PHP. It helps you download, install and keep up to date PHP extensions and libraries.
Installing Composer requires just a couple of minutes:
- first, make sure you have a web development environment already installed (XAMPP, WAMP, EasyPHP etc.) as Composer needs a PHP executable to work;
- download the Composer installation file from here (under “Windows Installer”) and run it;
- follow the installation instructions, and make sure you can select a PHP executable:

- once the installation is complete, you will be able to use the Composer command line tools to install PHPMailer.
Now you need to open a terminal (by executing “cmd.exe” or looking for “Command prompt” in the Start menu) and navigate to the directory where you want to install the Composer packages including PHPMailer (if you need help using the terminal just leave me a comment below).
For example, let’s use “C:\xampp\composer” as installation directory. First create the directory, then go back to the terminal and move into the directory by typing “cd C:\xampp\composer”.
Then, simply execute the command: “composer require phpmailer/phpmailer” as shown in the following image:

PHPMailer will be installed and you’ll be ready to use it.
Composer will generate an “autoload.php” file you can use to include the installed libraries, in this case PHPMailer. This file is located under the “vendor” directory by default, although you can configure Composer to use a different directory name.
So, assuming your installation directory is “C:\xampp\composer”, you need to include the “C:\xampp\composer\vendor\autoload.php” file.
Also, because now PHPMailer defines its classes under the PHPMailer\PHPMailer namespace, it’s a good idea to make use of the use directive at the beginning of your script, aliasing the PHPMailer\PHPMailer\PHPMailer and PHPMailer\PHPMailer\Exception classes:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'C:\xampp\composer\vendor\autoload.php';
$email = new PHPMailer(TRUE);
/* ... */
Installing Composer and PHPMailer on Linux
Many GNU/Linux distributions include the Composer package in their repositories.
On Debian-like systems (including Ubuntu), for example, you can simply use the “apt-get” command to install Composer (installing Composer from the source code is outside the scope of this guide, but if you need help with it feel free to ask me).
Once Composer is installed, you can use the Composer command line executable to install PHPMailer inside a directory of your choice, just like we already saw for the Windows installation (you can use the very same command):

Now PHPMailer is installed.
You can include the “autoload.php” file and set the namespace aliases just like for the Windows installation (changing the file path, of course).
Installing PHPMailer without Composer
If you prefer not to use Composer, you can just download the PHPMailer source files and include the required files manually.
You can download the ZIP file with the source code from the PHPMailer homepage, clicking on the “Clone or download” green button (on the right) and then selecting “Download ZIP”. Unzip the package inside the directory where you want to save the source files.
Then you just need to include the needed classes files in your PHP script.
As a minimum, you want to include the main PHPMailer class, the Exception class (for error handling) and probably the SMTP class too, if you are going to connect to an SMTP server for mail delivery.
You should also set the namespace aliases just like you saw before for the Composer installation.
Assuming your source code directory is “C:\PHPMailer”, this is how your PHP script will look like:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
/* Exception class. */
require 'C:\PHPMailer\src\Exception.php';
/* The main PHPMailer class. */
require 'C:\PHPMailer\src\PHPMailer.php';
/* SMTP class, needed if you want to use SMTP. */
require 'C:\PHPMailer\src\SMTP.php';
$email = new PHPMailer(TRUE);
/* ... */
Keeping PHPMailer up to date
If you choose the Composer installation method, you can keep your PHPMailer installation up to date by executing the “update” Composer command.
The syntax is the same on both Windows and Linux. Just go to the installation directory (where you issued the installation command) and execute the update:
composer update
If you choose not to use Composer, then you will need to manually download the new ZIP file from the PHPMailer homepage and overwrite the previous installation (following the same steps).
In either case, before updating your installation is a good idea to look at the changelog file and the update notes, just to be sure that your PHP applications are compatible with the new PHPMailer version.
HOW TO SEND YOUR FIRST EMAIL WITH PHPMAILER
To send an email with PHPMailer you need to create a PHPMailer object, set some parameters using its methods and attributes and finally call the send() method.
Let’s see a basic example so you can understand how this class works (don’t worry about the details for now, we will cover them in the next chapter).
In all the examples I will use the Windows installation path, because I am working on my local XAMPP development environment. If you are using Linux just change the include paths accordingly.
<?php
/* Namespace alias. */
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
/* Include the Composer generated autoload.php file. */
require 'C:\xampp\composer\vendor\autoload.php';
/* If you installed PHPMailer without Composer do this instead: */
/*
require 'C:\PHPMailer\src\Exception.php';
require 'C:\PHPMailer\src\PHPMailer.php';
require 'C:\PHPMailer\src\SMTP.php';
*/
/* Create a new PHPMailer object. Passing TRUE to the constructor enables exceptions. */
$mail = new PHPMailer(TRUE);
/* Open the try/catch block. */
try {
/* Set the mail sender. */
$mail->setFrom('darth@empire.com', 'Darth Vader');
/* Add a recipient. */
$mail->addAddress('palpatine@empire.com', 'Emperor');
/* Set the subject. */
$mail->Subject = 'Force';
/* Set the mail message body. */
$mail->Body = 'There is a great disturbance in the Force.';
/* Finally send the mail. */
$mail->send();
}
catch (Exception $e)
{
/* PHPMailer exception. */
echo $e->errorMessage();
}
catch (\Exception $e)
{
/* PHP exception (note the backslash to select the global namespace Exception class). */
echo $e->getMessage();
}
See how PHPMailer uses a nice and easy OOP syntax?
The class’ constructor argument is set to TRUE to make PHPMailer use exceptions for error reporting.
If you prefer not to use exceptions, just omit the argument (or set it to FALSE). In this case you need to check the send() method return value and look for the error message in the $ErrorInfo attribute:
<?php
/* Namespace alias (don't need Exception this time). */
use PHPMailer\PHPMailer\PHPMailer;
/* Include the Composer generated autoload.php file. */
require 'C:\xampp\composer\vendor\autoload.php';
/* Create a new PHPMailer object. */
$mail = new PHPMailer();
/* Set the mail sender. */
$mail->setFrom('darth@empire.com', 'Darth Vader');
/* Add a recipient. */
$mail->addAddress('palpatine@empire.com', 'Emperor');
/* Set the subject. */
$mail->Subject = 'Force';
/* Set the mail message body. */
$mail->Body = 'There is a great disturbance in the Force.';
/* Finally send the mail. */
if (!$mail->send())
{
/* PHPMailer error. */
echo $mail->ErrorInfo;
}
It’s interesting to see how this script would look like if you were using the mail() function:
<?php
$from = 'Darth Vader <darth@empire.com>';
$to = 'Emperor <palpatine@empire.com>';
$subject = 'Force';
$message = 'There is a great disturbance in the Force.';
$headers = 'From: ' . $from;
if (!mail($to, $subject, $message, $headers))
{
echo "Error.";
}
else
{
echo "Message sent.";
}
Yes, the syntax is much worse 🙂
In the previous basic example, we did not tell PHPMailer to use a specific SMTP server. In this case PHPMailer uses the server email subsystem, just like mail() does.
Of course, you want to use your own SMTP connection parameters instead. Don’t worry: we’ll cover this in a minute.
Now let’s see how to use all the PHPMailer class functionalities.
Would you like to talk with me and other developers about PHPMailer, PHP and web development? Join my Facebook Group now: Alex PHP café
See you there 🙂
HOW TO USE THE PHPMAILER CLASS
Once you have created a PHPMailer object as seen in the previous examples, you can use the extensive PHPMailer class functionalities to set all the email parameters and attributes you need.
Let’s see the most useful PHPMailer methods.
- Set the sender (“From:”) address
This is probably the first thing you want to do. This method takes the sender address as first parameter, while the second parameter is optional and sets the sender name as will be seen by the recipients.
$mail->setFrom('darth@empire.com', 'Darth Vader');
- Add a recipient (“To:”) address
This is the second thing you want to do 🙂
Like for the sender, the second parameter is optional and specifies the name of the recipient.
$mail->addAddress('palpatine@empire.com', 'Emperor');
- Set the email subject
$mail->Subject = 'Force';
- Set the email body (the actual message)
The message body can include plain text and HTML code. If you want your email to be parsed as HTML, be sure to read the next point.
$mail->Body = 'There is a great disturbance in the Force.';
- Create an HTML email message
The isHTML() method sets the email body content type to HTML. You can also include an alternative, plain text body for those email clients that do not support HTML or that are configured not to display HTML messages.
It’s a good idea to always include a plain text alternative body to be sure everyone will be able to read your emails.
$mail->isHTML(TRUE);
$mail->Body = '<html>There is a great disturbance in the <strong>Force</strong>.</html>';
$mail->AltBody = 'There is a great disturbance in the Force.';
- Add an attachment
You can attach files to your email using the addAttachment() function.
This function takes two parameters: the first is the file path, and the second (optional) is the file name that the recipient will see. If not set, the same file name of the local file will be used.
Note that the file must be readable by the user running the PHP script (this is especially important under Linux systems).
$mail->addAttachment('/home/darth/star_wars.mp3', 'Star_Wars_music.mp3');
- Set a different reply-to address
You can specify which address the recipient will reply to when replying to your email. The default is the sender (“From:”) address, but you can change it.
$mail->addReplyTo('vader@empire.com', 'Lord Vader');
- Add CC and BCC recipients
$mail->addCC('admiral@empire.com', 'Fleet Admiral');
$mail->addBCC('luke@rebels.com', 'Luke Skywalker');
- Create an attachment from binary data
With PHPMailer you can create a “virtual” attachment from a binary stream, like a database binary field or a network stream. This means that you don’t have to save the data to a local file before sending it as an attachment.In the example below, we attach two files: the first contains the data from a “blob” (binary) SQL field and is named “db_data.db”, the second is created from a network stream (a PDF file) and is named “file.pdf”.
/* Binary stream from a database blob field */
$mysql_data = $mysql_row['blob_data'];
$mail->addStringAttachment($mysql_data, 'db_data.db');
/* Binary network stream */
$pdf_url = 'http://remote-server.com/file.pdf';
$mail->addStringAttachment(file_get_contents($pdf_url), 'file.pdf');
- Create an HTML message from a string
The msgHTML() method automatically reads an HTML string (or a local file, using file_get_contents() to read it) into an embedded HTML message. The second parameter tells the function where to look for images, so that they can be included inline in the message.
Note that this function will override both Body and AltBody attributes.
$mail->msgHTML(file_get_contents('contents.html'), __DIR__);
HOW TO USE A CUSTOM SMTP SERVER
PHPMailer lets you configure the SMTP connection parameters directly from your PHP script, using the PHPMailer class methods and attributes.
This is incredibly useful compared to mail(), which relies on the underlying system configuration instead.
The following example shows how you can use a specific SMTP server using SSL and authentication:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'C:\xampp\composer\vendor\autoload.php';
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom('darth@empire.com', 'Darth Vader');
$mail->addAddress('palpatine@empire.com', 'Emperor');
$mail->Subject = 'Force';
$mail->Body = 'There is a great disturbance in the Force.';
/* SMTP parameters. */
/* Tells PHPMailer to use SMTP. */
$mail->isSMTP();
/* SMTP server address. */
$mail->Host = 'smtp.empire.com';
/* Use SMTP authentication. */
$mail->SMTPAuth = TRUE;
/* Set the encryption system. */
$mail->SMTPSecure = 'tls';
/* SMTP authentication username. */
$mail->Username = 'smtp@empire.com';
/* SMTP authentication password. */
$mail->Password = 'iamyourfather';
/* Set the SMTP port. */
$mail->Port = 587;
/* Finally send the mail. */
$mail->send();
}
catch (Exception $e)
{
echo $e->errorMessage();
}
catch (\Exception $e)
{
echo $e->getMessage();
}
Of course, you need to use the correct connection parameters, including the server encryption capabilities and the TCP port it listens to.
A more advanced SMTP related attribute is the SMTPOptions array. If you are using SMTP encryption, PHPMailer passes this array to the underlying PHP stream_context_create() function.
You can use the SMTPOptions attribute to set advanced SSL context options. While you won’t need to use it most of the time, in some cases it can be really useful.
For example, if you have your own SMTP server which uses a self-signed certificate, the SMTP connection will probably fail for the lack of a valid certification authority signature. This is a quite common scenario in work environments.
In these cases, you can use the SMTPOptions attribute to tell PHPMailer (and the PHP SSL subsystem) to ignore this issue.
In the following example we set the verify_peer and verify_peer_name parameters to FALSE and the allow_self_signed parameter to TRUE in order to disable some security checks:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'C:\xampp\composer\vendor\autoload.php';
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom('darth@empire.com', 'Darth Vader');
$mail->addAddress('palpatine@empire.com', 'Emperor');
$mail->Subject = 'Force';
$mail->Body = 'There is a great disturbance in the Force.';
/* SMTP parameters. */
$mail->isSMTP();
$mail->Host = 'smtp.empire.com';
$mail->SMTPAuth = TRUE;
$mail->SMTPSecure = 'tls';
$mail->Username = 'smtp@empire.com';
$mail->Password = 'iamyourfather';
$mail->Port = 587;
/* Disable some SSL checks. */
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
/* Finally send the mail. */
$mail->send();
}
catch (Exception $e)
{
echo $e->errorMessage();
}
catch (\Exception $e)
{
echo $e->getMessage();
}
A PRACTICAL VIDEO EXAMPLE
Why don’t you look at a practical video example? This nice video from Mr. Digital shows how to create a PHPMailer script:
DEBUGGING AND ERROR HANDLING
If something goes wrong while trying to send the message, the PHPMailer object throws and exception (if TRUE is passed to the constructor) and saves the error information inside the $ErrorInfo attribute.
The best way to handle errors is to use a try/catch block to catch the exception, as shown in the previous examples. The PHPMailer/Exception class provides the errorMessage() method to retrieve the error message directly from the exception object.
SMTP DEBUG
You can set the SMTPDebug attribute to enable on screen SMTP connection debugging.
This kind of debugging output can be extremely useful in the development phase, because it lets you see if something goes wrong with the SMTP connection.
Note that the SMTPDebug output should be used for debugging purposes only, because it can expose sensitive data to remote clients.
The SMTPDebug argument can be set to an integer value between 0 (the default, no output is generated) and 4 (low-level info output is displayed). If your emails are not being sent, I suggest you set this value to 4 and see what happens:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'C:\xampp\composer\vendor\autoload.php';
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom('darth@empire.com', 'Darth Vader');
$mail->addAddress('palpatine@empire.com', 'Emperor');
$mail->Subject = 'Force';
$mail->Body = 'There is a great disturbance in the Force.';
$mail->isSMTP();
$mail->Host = 'smtp.empire.com';
$mail->SMTPAuth = TRUE;
$mail->SMTPSecure = 'tls';
$mail->Username = 'smtp@empire.com';
$mail->Password = 'iamyourfather';
$mail->Port = 587;
/* Enable SMTP debug output. */
$mail->SMTPDebug = 4;
$mail->send();
}
catch (Exception $e)
{
echo $e->errorMessage();
}
catch (\Exception $e)
{
echo $e->getMessage();
}
ERROR MESSAGES LOCALIZATION
PHPMailer supports error messages localization. You can use one of the many (48 at the moment of writing) already available translations (you can find the list here) or even create a customized language set by yourself.
To set the language, just call the setLanguage() method:
/* Set language to Italian using a default translation set. */
$mail->setLanguage('it');
/* Or use your own translation set
(in this case you need to specify the translation file path). */
$mail->setLanguage('klingon', 'C:\PHPMailer\myLanguages\');
If you want to use your own translation set, then you need to pass the translation file path to the function as second parameter (with a trailing directory separator). If you are using one of the default ones, then leave the second parameter empty.
HOW TO USE PHPMAILER WITH GOOGLE (GMAIL) SMTP
The Google SMTP server is smtp.gmail.com. It uses TLS-encrypted connections and listens to port 587.
The PHPMailer SMTP configuration should therefore use those settings:
/* Use SMTP. */
$mail->isSMTP();
/* Google (Gmail) SMTP server. */
$mail->Host = 'smtp.gmail.com';
/* SMTP port. */
$mail->Port = 587;
/* Set authentication. */
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'tls';
SMTP servers usually require clients to authenticate themselves with username and password before they are allowed to send messages. Google’s SMTP does too, but you may need to take additional steps to make it work.
Google’s SMTP authentication steps with PHPMailer depend on whether you have Google two-step verification enabled or not.
GMAIL AUTHENTICATION WITH 2-STEP VERIFICATION DISABLED
If you don’t have Google two-step verification enabled, you can try using your own username (in this case, your email address) and password to login:
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->Port = 587;
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'tls';
/* Username (email address). */
$mail->Username = 'myusername@gmail.com';
/* Google account password. */
$mail->Password = 'mypassword';
That *may* work, however Google is very suspicious about unusual log in attempts and may refuse to authorize your PHPMailer script authentication process. This is also explained in this PHPMailer’s Troubleshooting document.
Google’s SMTP may ask the “client” (in this case, the PHPMailer script) to log in with the web browser first, or to follow this page‘s instructions.
If you don’t want to enable 2-step verification, you probably must tell Google to “Allow less secure apps” login attempts for the PHPMailer’s authentication to be accepted.
To do that you can follow these instructions, or just go here while logged in with the Google account you want to use.
After you have authorized “less secure apps” connections, you can try again and see if it works (you may need to wait for a couple of hours for the change to take effect).
If it still doesn’t work, you are left with two options: enable the 2-step verification and follow the instructions below or use the XOAUTH2 authentication process as described later in this tutorial.
Your choice 🙂
GMAIL AUTHENTICATION WITH 2-STEP VERIFICATION ENABLED
If you enabled two-step verification then you need to create an “App password” and use it to log in with PHP, because you won’t be able to use the second authentication factor with PHPMailer (which involves using an authentication app or authorizing the access with your smartphone).
An “app password” is a string you can use to login without the second authentication factor. To create one, just follow Google’s instructions at this page or just open this link.
From there, choose a name for your app (for example, “PHPMailer”) and press the “Generate” button as seen in this image:

After pressing the button, you will obtain a 16-chars string you can use to log in. Be sure to copy it right away, because you won’t be able to retrieve it later (if you lose it, you will need to create a new app password from scratch):

Now all you need to do is use this new string as password in your PHPMailer configuration (without spaces, those are there just for readability):
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->Port = 587;
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'tls';
$mail->Username = 'myusername@gmail.com';
/* App password. */
$mail->Password = 'eqwvrwlbbizcsdcz';
USING GMAIL WITH XOAUTH2 AUTHENTICATION
XOAUTH2 is Google’s recommended authentication method. While it’s a quite complex protocol, thanks to PHPMailer is possible to use it without much difficulty.
PHPMailer’s XOAUTH2 implementation relies on the league/oauth2-client library, that must therefore be installed on your system. Specifically, you need to install the league/oauth2-google package.
The easiest way to install it is to use Composer. If you chose to install PHPMailer with Composer, then you can do the same with the league/oauth2-google library: just go to the Composer installation directory and type “composer require league/oauth2-google”:

You can also install this library inside another directory, but in this case you will need to include two autoloader.php files. If you didn’t use Composer to install PHPMailer, just install the OAUTH2 library in a new directory.
Unfortunately, installing league/oauth2-google without Composer is a bit difficult, because it requires a few libraries to be installed as well. If you really hate Composer and don’t want to use it, you will need to download them all manually and include them in your scripts.
Once you have league/oauth2-google installed, you will need to perform some steps with the Google account you are going to use.
All these steps are explained in detail in this PHPMailer XOAUTH2 tutorial. Follow all the steps but stop before the last “Configure your email script” paragraph, because it’s outdated and the example code there no longer works.
Keep in mind that you will need to have a working development environment, because you will need to edit a PHPMailer file (get_oauth_token.php) and run it with a web browser.
After you have completed all the required steps, you will have three authentication strings:
- the Client ID
- the Client Secret
- and the Refresh Token
You need to use them in your PHPMailer XAUTH2 authentication process.
Next you need to configure the PHPMailer script, include the OAUTH2 library and set the authentication parameters. The required steps are:
- set namespace aliases for the PHPMailer OAuth and league Google classes;
- include the league library (if you used the same Composer installation directory then the autoloader.php file will take care of that);
- set the script time zone to UTC; this is needed for proper time synchronization with the Google server;
- set the PHPMailer class AuthType attribute to “XOAUTH2”;
- create a league/Google object and a PHPMailer/OAuth object with the authentication strings you got in the previous steps and use them for the authentication process.
In this final example you can see how this is done:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
/* New aliases. */
use PHPMailer\PHPMailer\OAuth;
use League\OAuth2\Client\Provider\Google;
/* Composer autoload.php file includes all installed libraries. */
require 'C:\xampp\composer\vendor\autoload.php';
/* If you installed league/oauth2-google in a different directory, include its autoloader.php file as well. */
// require 'C:\xampp\league-oauth2\vendor\autoload.php';
/* Set the script time zone to UTC. */
date_default_timezone_set('Etc/UTC');
/* Information from the XOAUTH2 configuration. */
$google_email = 'myaddress@gmail.com';
$oauth2_clientId = 'CliendIdString';
$oauth2_clientSecret = 'ClientSecret';
$oauth2_refreshToken = 'RefreshToken';
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom($google_email, 'Darth Vader');
$mail->addAddress('palpatine@empire.com', 'Emperor');
$mail->Subject = 'Force';
$mail->Body = 'There is a great disturbance in the Force.';
$mail->isSMTP();
$mail->Port = 587;
$mail->SMTPAuth = TRUE;
$mail->SMTPSecure = 'tls';
/* Google's SMTP */
$mail->Host = 'smtp.gmail.com';
/* Set AuthType to XOAUTH2. */
$mail->AuthType = 'XOAUTH2';
/* Create a new OAuth2 provider instance. */
$provider = new Google(
[
'clientId' => $oauth2_clientId,
'clientSecret' => $oauth2_clientSecret,
]
);
/* Pass the OAuth provider instance to PHPMailer. */
$mail->setOAuth(
new OAuth(
[
'provider' => $provider,
'clientId' => $oauth2_clientId,
'clientSecret' => $oauth2_clientSecret,
'refreshToken' => $oauth2_refreshToken,
'userName' => $google_email,
]
)
);
/* Finally send the mail. */
$mail->send();
}
catch (Exception $e)
{
echo $e->errorMessage();
}
catch (\Exception $e)
{
echo $e->getMessage();
}
CONCLUSION
Mastering PHP email handling is a big advantage.
With this tutorial, you have learned all you need to know to use PHPMailer at its full potential: how to install it, how to use its functionalities, how to configure SMTPS connections (including Gmail’s), error handling and more.
Feel free to bookmark this page and return here for reference as needed.
If you have any issue, check the PHPMailer Troubleshooting guide or just leave me a comment below. You are also invited to join my Facebook Group (Alex PHP café) where me and my community will be very glad to help you!
Now, I’m curious: how do YOU use email in your web applications? I’m looking forward to hearing from you!
P.s. If this guide has been helpful to you, please spend a second of your time to share it… thanks!
Alex
MySQLi vs PDO: which one is best for you?
Get my weekly PHP tips and the bonus PDF, absolutely free.
Hi Alex, I’m new to PHPMailer, and I wonder how to limit file size allowed for an attachment. Would please kindly explain? Thanks a lot!
Hi Lamia,
you can use the PHP native filesize() function to get the size (in bytes) of a local file.
For example, if the file that is going to be attached is submitted by the remote user, you can check its size with filesize() after the standard upload chain.
If the value from filesize() exceeds your limit, you return an error and you don’t send the email.
Thanks for the tips.
But I can’t find the sent mails in the email sent folder.
How can I resolve this?
Hi Richard,
many modern email providers should do that automatically.
But in your case, you probably need to do that manually. Try following the steps described here: https://stackoverflow.com/questions/8561495/sent-mails-with-phpmailer-dont-go-to-sent-imap-folder
I am still confused on setting this up, i mean u used composer in the tutorial video but i am trying to run it in a live server, I have downloaded the php mailer component, attached it to a form, set up the variables to request data from the form, but nothing happens when i click send. Why
Hi Simon,
try running the PHPMailer script manually to see if it works. Be sure to enable the debugging flag:
$mail->SMTPDebug = 4;
You can paste here the result messages.
thanks , i am having issue mailer was working before but suddenly stopped working
i got this error
Message could not be sent. Mailer Error: SMTP Error: Could not connect to SMTP host.
If it was working before, it’s probably a connection issue. Can you manually reach the SMTP server? (With a ping or a telnet connection)
Hi Alex,
I am using PHPMailer in my server with ISPConfig and I managed to make it work except for DKIM signature. My problem is the following: ISPConfig creates the DKIM keys and stores it in /var/lib/amavis folder. However, this folder is not accessible by the apache user (www-data), so DKIM does not work when executing a php file through a browser (it does when doing so from command line).
How can I fix this and let the apache user access the files in this folder without changing the group owner (amavis)?
Thank you in advance
Hi Javier,
are you sure the PHP script needs read access to the DKIM keys? I think that only the SMTP server needs to access them.
Anyway, you can try adding the www-data user to the amavis group. Apache will be able to read the dkim amavis folder if it’s group-readable.
Hi Alex. Great article.
Everything is working and all email sent form the PHPMailer were sent accept those sent to gmail accounts.
Those sent to gmail accounts bounces back with diagnostic code : smtp; 550-5.7.26 This message does not have authentication
information or fails to 550-5.7.26 pass authentication checks. To best
protect our users from spam, the 550-5.7.26 message has been blocked.
Please visit 550-5.7.26
https://support.google.com/mail/answer/81126#authentication for more 550
5.7.26 information. b64si4397482pfg.87 – gsmtp
Do you have any suggestion on the issue?
Hi,
it seems like the SMTP you are using is not configured properly as far as authentication is concerned.
Google is particularly picky on this.
Try using this tool: https://mxtoolbox.com/dmarc.aspx
Enter your SMTP domain to check its authentication status.
Would be awesome a tutorial mixing phpmailer working code and google recaptcha code. I have the phpmailer code working here but i dont know how to “merge” the recaptcha code on php. Yeah, yeah im code stupid individual.
Hi am hoping there’s a YouTube video for this, if there is kindly send please
Sorry Daniel, there’s no video at the moment.
Hi, Alex!
I’m trying to get a token but once I select Google provider from “get_oauth_token.php”, the script eventually runs out of memory.
“Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 20480 bytes) in C:\xampp\composer\vendor\autoload.php on line 41”
line 41 is basically the very last line which is also a comment line.
Any idea why it is so?
Can you please share the autoload.php file so I can take a look?
You can use Pastebin and share the link here.
Thanks.
autoload.php
https://hastebin.com/fenumenixo.xml
Thank you!
Thanks Draak.
This autocomposer.php looks strange as it seems to include itself.
Maybe you have edited it adding the PHPMailer code?
If so, you need to restore it as it was (it should only have the require directive) and include it from another script.
That was silly of me. I restored the autoload.php file and created yet another one in phpmailer directory. Now it works and I have the token. Thank you!
Good to know you solved it!
Hi,
Can you give me a sample how to send email to customer from customer table in mysql.
Thank you
Hi Henry,
you need to execute an SQL query to get the customers’ addresses. For example:
“SELECT * FROM customers”
You also want to filter the result to only get the customers you need to send the email to.
Then, you can iterate through the query results and send the emails.
Hi Alex, I just read this peice and haven’t tried it yet but I have a problem sending smtp. I’m using a helpdesk software and all smtp settings have been put to place but when I’m testing the smtp connection I get this error
Could not start TLS connection encryption protocol
the error logs….
Resolving SMTP server domain “smtp.gmail.com”…
Connecting to SMTP server “smtp.gmail.com” port 587…
Connected to SMTP server “smtp.gmail.com”.
S 220 smtp.gmail.com ESMTP u23sm16609016wru.94 – gsmtp
C EHLO localhost
S 250-smtp.passthru
S 250-SIZE 35882577
S 250-8BITMIME
S 250-STARTTLS
S 250-ENHANCEDSTATUSCODES
S 250 SMTPUTF8
C STARTTLS
S 220 2.0.0 Ready to start TLS
Starting TLS cryptograpic protocol
Please what do you think might cause this? my settings is just like the one youve explained above smtp host, port, mail username and password….Please help
Hi Ibrahim,
try adding this code before sending the email:
/* Disable some SSL checks. */
$mail->SMTPOptions = array(
‘ssl’ => array(
‘verify_peer’ => false,
‘verify_peer_name’ => false,
‘allow_self_signed’ => true
)
);
If it still doesn’t work, please come over my Facebook group so we can talk there: https://www.facebook.com/groups/289777711557686/
Thanks Alex for the solution, I’ve tried and it got rid of the tls problem however I am getting this error message
https://pastebin.com/CJM6LjP9
Please how do I go about this? My gmail credentials are correct I’ve checked
PS: I created a single mailer file to test this code first before integrating into my project, hence the file consists of just what we have here on this page. Thanks
Please disregard the above comment, I’ve been able to send the mail successfully now. The username and password problem was because of permission for less secure apps in gmail, Once I turned it on, it works.
Thanks again, I’m glad I came here.
Good to know you solved it!
Hi! Great tutorial! Can you help me make PHPMailer work with Office 365 connection?
Connection failed. Error #2: stream_socket_client(): php_network_getaddresses: getaddrinfo failed: This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server.
Here’s my config:
$mail->Host = ‘smtp.office365.com’;
$mail->SMTPAuth = true;
$mail->Username = ‘myemail@domain.com’;
$mail->Password = ‘mypassword’;
$mail->SMTPSecure = ‘tls’;
$mail->Port = 587;
Appreciate it!
Hi Jessa,
it seems a network issue. Can you ping smtp.office365.com from the server where you are running the PHP script?
Hi Alex,
I my code is also not working. When I am pinging to my server terminal smtp.office365.com. It showed me socket: Operation not permitted. Kindly Guide me.
Hi,
the “Operation not permitted” message usually means the packages are blocked by a firewall or by a kernel rule. Maybe you have a firewall preventing you from reaching the SMTP?
Hi Alex!
Superb tutorial, helped me a lot, thanks!
Thank you LalleR. I’m glad it helped.
2020-06-18 15:02:34 Connection: opening to smtp.gmail.com:587, timeout=300, options=array()
2020-06-18 15:02:34 Connection failed. Error #2: stream_socket_client(): unable to connect to smtp.gmail.com:587 (Network is unreachable) [/…/phpmailer/phpmailer/src/smtp.php line 374]
2020-06-18 15:02:34 SMTP ERROR: Failed to connect to server: Network is unreachable (101)
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
I dont know what is the problem.Can you help me in figuring this out?
Hi Pranav,
I edited your comment to remove the file path (just for security).
The error says that your script cannot reach smtp.gmail.com on port 587. It seems a network issue.
Maybe your hosting provider is blocking outbound SMTP connections. Can you try contacting their support?
Hello,
I’ve been following your installation guide perfectly, but i have still the same problem.
I got this error : Undefined type :’use PHPMailer\PHPMailer\PHPMailer;’
I still can’t understand where it came from after a lot or research.
Do you have any solutions ?
Hi Kylian,
can you share your code so I can take a look?
You can use Pastebin and share the link here in the comments: https://pastebin.com/
Hi please I am a beginner in PHP
I have issues with the phpmail send function
I followed all your steps but yet when I ran the script on my xampp server I got couldn’t connect to SMTP() server
setFrom(‘chiemeluchukwuemekalum@gmail.com’, ‘Daniel Chiemelu’);
$mail->addAddress(‘chiemeluchukwuemekalum@outlook.com’, ‘Emekalum’);
$mail->Subject = ‘Force’;
$mail->Body = ‘There is a great disturbance in the Force.’;
/* SMTP parameters. */
/* Tells PHPMailer to use SMTP. */
$mail->isSMTP();
/* SMTP server address. */
$mail->Host = ‘smtp.gmail.com’;
/* Use SMTP authentication. */
$mail->SMTPAuth = TRUE;
/* Set the encryption system. */
$mail->SMTPSecure = ‘tls’;
/* SMTP authentication username. */
$mail->Username = ‘chiemeluchukwuemekalum@gmail.com’;
/* SMTP authentication password. */
$mail->Password = ”;
/* Set the SMTP port. */
$mail->Port = 587;
/* Finally send the mail. */
$mail->send();
}
catch (Exception $e)
{
echo $e->errorMessage();
}
catch (\Exception $e)
{
echo $e->getMessage();
}
Hello sir, Does PHP 5 support php mailer?
Only PHP 5.5 and later versions.
Hi Alex, congratulations for the guide, I followed your video and everything works perfectly …
But now I was wondering if there was a way to always use phpmailer but without putting the smtp authentication data in the file, as it is not very secure.
Or at least if you know other alternatives without authentication.
Thanks and congratulations again for the guide. ; )
Hi Roberto,
yes, you can put the SMTP authentication data in a different PHP script and include it when needed.
In this script, the SMTP username and password are saves as variables so you can use them for the PHPMailer configuration after you include the file.
You can store this include script outside of the webserver root, to make it more secure.
An alternative is to store the SMTP credentials on the database and retrieve them when needed.
Hello Alex,
Usefull information..But i am having problem in phpmailer_smtp update.
i uninstalled the older version but when i am going to install new version of phpmailer in module section it says “PHPMailer SMTP is already installed.”.
What should i do? please help
Hi Darshana,
are you using Composer to update the PHPMailer package?
If so, can you share the exact commands you are using?
Thank you
Hi Alex,
A very useful tutorial. I used your steps + the Mr Digital video and the tut at https://www.learnwptech.com/how-to-use-phpmailer-in-your-web-application/ to get my final script working (and some research at my ISP).
I’m now going to read your PHP Security tutorial.
Thank you for sharing,
Dave.
Thank you for your feedback, Dave.
Hi this was so helpful in getting the mailing system ready. Thank you so much for your generous contribution. I wish to know if there is any possibility to create a inbox/sent items page like email clients by using oauth?
The standard PHP IMAP library unfortunately doesn’t support OAUTH authentication.
You can try using the third-party library Laminas-mail: https://docs.laminas.dev/laminas-mail/
It’s the Zend-mail library under another name and it *may* support OAUTH, but I’m not sure (Zend-mail did support OAUTH, but I’m not sure if the new Laminas-mail does as well).
hello, thank you so much for this tutoriel, c’est bien expliqué! but i still have a problem if you can help me, i dont really know how to fix it, thanks it advance
i got this errors!
2020-05-12 21:50:35 Connection: opening to ssl://smtp.gmail.com:587, timeout=300, options=array()
2020-05-12 21:50:35 Connection failed. Error #2: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:error:1408F10B:SSL routines:ssl3_get_record:wrong version number [C:\wamp64\www\projet\PHPMailer\src\SMTP.php line 344]
2020-05-12 21:50:35 Connection failed. Error #2: stream_socket_client(): Failed to enable crypto [C:\wamp64\www\projet\PHPMailer\src\SMTP.php line 344]
2020-05-12 21:50:35 Connection failed. Error #2: stream_socket_client(): unable to connect to ssl://smtp.gmail.com:587 (Unknown error) [C:\wamp64\www\projet\PHPMailer\src\SMTP.php line 344]
2020-05-12 21:50:35 SMTP ERROR: Failed to connect to server: (0)
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
message sentSMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
Hi Sofiane,
it’s likely an SSL-related error. Can you add this line of code to get more debug messages?
$mail->SMTPDebug = 4;
Also, can you share the PHPMailer code so I can take a look? Please use Pastebin (https://pastebin.com/) and share the link here.
Thanks
I am trying out phpmailer on behalf of a local walking group. The default works, but I would like to send a copy to the person that completes the form and I don’t know how. My form code is:
Your Name:
Email Address:
Message:
Post
and the php is:
$pp = new FormHandler();
$validator = $pp->getValidator();
$validator->fields([‘Name’,’Email’])->areRequired()->maxLength(50);
$validator->field(‘Email’)->isEmail();
$validator->field(‘Message’)->maxLength(6000);
$pp->requireReCaptcha();
$pp->getReCaptcha()->initSecretKey(‘xxx’);
$pp->sendEmailTo(‘me@home’); // ← Your email here
echo $pp->process($_POST);
I believe I have to add:
$pp->addAddress(something here);
but don’t know what. I have absolutely no php knowledge. Are you able to offer any guidance please?
Thank you.
Clive
Sorry, I pasted the html and it appears to have interpreted it not pasted it. I’ve removed symbols so maybe you can make sense of this:
form method=”post” id=”reused_form”
label for=”name” Your Name: /label
input id=”name” type=”text” name=”Name” required maxlength=”50″
label for=”email” Email Address: /label
input id=”email” type=”email” name=”Email” required maxlength=”50″
label for=”message” Message: /label
textarea id=”message” name=”Message” rows=”10″ maxlength=”6000″ required /textarea
div class=”g-recaptcha” data-sitekey=”6LeOk-8UAAAAAM5s18v6u59HRNd_jRICFglUbghP” /div
button class=”button-primary” type=”submit” Post /button
/form
Hi Clive,
the first step is to get the client email from the “Email” field. It seems you are using the FormHandler class to retrieve and validate the email. Is this step ok?
Then, you need to call addAddress() on the PHPMailer object, using the client email as argument. You can also include the client name as second argument.
To help you further I need to see the code. Could you please share it using Pastebin?
Thanks Alex.
Been struggling to get this mailer working for a week now. 15 Minutes into your tutorial and it is running smoothly.
Good work, Nico. Glad I could help.
Hi, Very nice post, thanks so much for your help,
Please mt issue is that its working succesfully for me as i implemented it in my first laptop wamp server, when i take the code to another laptop wamp server showing an Error:
SMTP Error: Could not connect to SMTP host, while thesame code is still working on the other computer.
Hi,
if the PHP code is the same, it could be a connection issue.
Can you manually connect to the SMTP server from the second laptop?
I donot know the process please if you can explain, and i was using Gmail OAuth, in the morning it was working normal and now its showing this error: SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting, another time this:
SMTP Error: Could not connect to SMTP host.
i deleted the credentials and created another new one from google but still thesame error.
Can you please try increasing the debug level to 4, like this:
$mail->SMTPDebug = 4;
and share the error here?
Hopefully we can obtain more details about the problem.
Hello Alex,
I appreciated your efforts …
I am using wamp server instead of xamp server on windows platform to implement your tutorial steps. I use manual installation method to install phpmailer instead of using composer.
However when i ran the script i ended up have the following issue:
“Could not instantiate mail function.”
Below is my php script:
setFrom(‘abdulsadeeq.as@gmail.com’, ‘Abdul Elite’);
/* Add a recipient. */
$mail->addAddress(‘gemsglobals@gmail.com’, ‘gemsPOS’);
/* Set the subject. */
$mail->Subject = ‘myFirst Test’;
/* Set the mail message body. */
$mail->Body = ‘There is a great i confirmed my mailing gateway.’;
/* Finally send the mail. */
$mail->send();
}
catch (Exception $e)
{
/* PHPMailer exception. */
echo $e->errorMessage();
}
catch (\Exception $e)
{
/* PHP exception (note the backslash to select the global namespace Exception class). */
echo $e->getMessage();
}
?>
Kindly help me fix it.
Hi Abdul,
by default PHPMailer uses the system mail service. On Linux systems, this is the “mail” command, but on Windows this is not available.
The best solution is to explicitly configure your own SMTP server. Is this possible for you?
Thank you for your support Mr Alex.
Actually i have no sufficient knowledge to configure my own SMTP server on windows .
I will be much grateful if you can kindly help me get it done.
You can configure the PHPMailer object like this:
$mail->isSMTP();
$mail->Host = ‘smtp server’;
$mail->SMTPAuth = TRUE;
$mail->SMTPSecure = ‘tls’;
$mail->Username = ‘username’;
$mail->Password = ‘password’;
$mail->Port = 587;
The ‘smtp server’ must be the real SMTP server of your email provider. For example, if you are using a GMail address, the SMTP server is ‘smtp.gmail.com’
The ‘username’ is your own email address, and the ‘password’ is of course your password.
This configuration should work most of the time. Please give it a try and let me know how it goes.
Hi, I tried it but I’m getting this error: Parse error: syntax error, unexpected ‘use’ (T_USE) in C:\wamp64\www\newproject\contact-form.php on line 77
Below is my full code, I don’t know what’s wrong
isSMTP();
/*Server Configuration*/
$mail->Host = ‘mail.company.com’; // Which SMTP server to use.
$mail->Port = 587; // Which port to use, 587 is the default port for TLS security.
$mail->SMTPSecure = ‘tls’; // Which security method to use. TLS is most secure.
$mail->SMTPAuth = true; // Whether you need to login. This is almost always required.
$mail->Username = “email@company.com”; // Your email address.
$mail->Password = “emailpassword”; // Your email login password.
/*Message Configuration*/
$mail->setFrom($email, $name); // Set the sender of the message.
$mail->addAddress(’email@website.com’, ‘Company name’); // Set the recipient of the message.
$mail->Subject = ‘Contact form submission from your Website’; // The subject of the message
/*Message Content*/
$mail->isHTML(true);
$mail->Body = ‘Name: ‘ . $name . ” . ‘Phone: ‘ . $phone . ” . ‘Email: ‘ . $email . ” . ‘Message: ‘ . ” . $message . ”; // Set a plain text body.
if ($mail->send()) {
$result_success = “Your message was sent successfully! We Would get back to your shortly ” .
//Here is the solution for when the for is submitted with the successful message all form fields to get cleared.
$name = false;
$email = false;
$phone = false;
$message = false;
} else {
$result_error = “Something went wrong. Check your Network connection and Please try again.”;
}
}
}
function check_input ($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
For some reason, my code was truncated. These are the codes leading to the beginning of the above code:
<?php
$name = $email = $company = $phone = $message = "";
$nameErr = $emailErr = $companyErr = $phoneErr = $messageErr = "";
$result_success = "";
$result_error = "";
if($_SERVER["REQUEST_METHOD"] == "POST") {
if(empty($_POST["name"])) {
$nameErr = "Name is required";
}
else {
$name = check_input($_POST["name"]);
}
//Check if name only contains letters and whitespace
if(!preg_match("/^[a-zA-Z]*$/", $name)) {
$nameErr = "Only letters and whitespaces allowed";
}
if(empty($_POST["email"])) {
$emailErr = "Email is required";
}
else {
$email = check_input($_POST["email"]);
}
//Check if email is properly inputed
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
}
if(empty($_POST["company"])) {
$company = "";
}
else {
$company = check_input($_POST["company"]);
}
if(empty($_POST["phone"])) {
$phone = "";
}
else {
$phone = check_input($_POST["phone"]);
}
//Check if phone only contains number
if(!preg_match("/^[0-9]{0,10}$/", $phone)) {
$phoneErr = "Input the right phonenumber format, Max 11 characters";
}
if(empty($_POST["message"])) {
$messageErr = "Message is required";
}
else {
$message = check_input($_POST["message"]);
}
if(empty($nameErr) && empty($emailErr) && empty($companyErr) && empty($phoneErr) && empty($messageErr)) {
// Here starts PHP Mailer
// Edit this path if PHPMailer is in a different location.
/* Namespace alias. */
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'C:\wamp64\www\ollytek\composer\vendor\autoload.php';
//'For main server' require './PHPMailer/PHPMailerAutoload.php';
$mail = new PHPMailer();
Hi,
you cannot use the “use” directive inside an IF statement. You need to move it in the global scope, outside of any IF.
Thank you. It works now!
Excellent tutorial for the newbie. Thanks for sharing your knowledge. This is my article like this: https://www.learnwptech.com/how-to-use-phpmailer-in-your-web-application/
thanks it worked for me
Thank you for your comment ETA, I’m glad it worked for you.
I am struck in process of installing composer .when I am writind cd c:\xampp\composer in cmd command it is showing folllowing errors
“The system cannot find the path specified.”Kindly please help me.
Hi Dipti,
does the c:\xampp\composer directory exist?
If not, you must create it first (you can use the standard Windows system explorer).
you are the own to create the files “c:\xampp\composer”
and then access it through cmd
Vous êtes génial Alex. Merci pour votre tuto, c’est formidable. Ca englobe tous les problèmes courants qu’on rencontre avec la bibliothèque PHPMailer. Vraiment merci beaucoup
Merci beaucoup, Audrey! 🙂
What a great tutorial, thanks for sharing.
I have been using the older version of phpmailer up until now i had to replace it to the new version.
I am trying to load phpmailer globaly and getting errors when doing that.
For example i have the main index.php file and i include with that the file second.php.
on index,php i load the code with this:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once(“/phpmailer/autoload.php”);
And in some files i needed to reload the
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
at the top of the pages each time. If by any chance you know a way that won’t require to reuse the same code each time that will be appreciated.
Thanks
Hi,
unfortunately, use directives are per file basis. Therefore, every single PHP script must declare them, even if they are included by a script that already has them.
I’m afraid there is no workaround as far as I know.
Hi Alex,
I have been trying to send mail using third party server to my mail address for the last 7-8 hours. But unable to get the mail i don’t know what is going wrong. i need your help. I am using wamp server.
the php code is as follows:
setFrom(‘admin@bunker.com’, ‘Stuart’);
$mail->addAddress(‘vikas@rizilianttech.com’, ‘Receiver’);
$mail->Subject = ‘Testing’;
$mail->Body = ‘Testing Phase’;
$mail->isSMTP();
$mail->Host = ‘in-v3.mailjet.com’;
$mail->SMTPAuth = TRUE;
$mail->SMTPSecure = ‘tls’;
$mail->Username = ’90c5aaf46076c3abe2c7adcf1ea299ef’;
$mail->Password = ‘c345c02e200550b7d24a9386673f49e7’;
$mail->Port = 587;
$mail->SMTPDebug = 4;
$mail->SMTPOptions = array(
‘ssl’ => array(
‘verify_peer’ => false,
‘verify_peer_name’ => false,
‘allow_self_signed’ => true
)
);
$mail->send();
}
catch (Exception $e)
{
/* PHPMailer exception. */
echo $e->errorMessage();
}
catch (\Exception $e)
{
/* PHP exception (note the backslash to select the global namespace Exception class). */
echo $e->getMessage();
}
?>
Hi Vikas,
are you getting any Exception or debug message?
Hi Alex
First,thank you for this toturial.
Second,I want to ask whether it is possible to send using stored email (in database).
because from what I understand,your tutorial uses non-database email.
Hi Muhammad,
sure you can. You just need to retrieve the email from the db before you can send it with PHPMailer.
The exact steps depend on how the email is stored on the database, of course.
Hi Alex,
Thank you for your tutorial. I have used the code as provided for the basic email and replaced the to email address. When use the browser to run the script the email sends just fine. However when i use the script in a cron job, no email is received. Can you help?
Hi Shaun,
what happens if you try running the script from the command line?
For example:
php -f ./script.php
Yes,
I would like to add my experience.
In my php mailer file I put one attachment for test. It normally sent if it I run script from web .. but if I run from cron service (bash, Linux Sinology) then no attachment is sent?!
Helppp please
Hi David,
thanks for sharing your experience.
If the message is sent but it lacks the attachment, there are two problems I can think of:
1. there is a problem with the variable with the attachment path, or…
2. there is a permission issue.
Case #2 happens if the attachment is readable by the web server (like Apache) but not by the user running the cron service. Can you check that?
I don’t get any errors, but the email that I receive looks like below.
This is a multi-part message in MIME format.
–b1_jJbWaSTAkopK9vM6vR9GTUaEFzNPIcbXXAiO2detU
Content-Type: text/html; charset=us-ascii
this is the body of the email
–b1_jJbWaSTAkopK9vM6vR9GTUaEFzNPIcbXXAiO2detU
Content-Type: application/pdf; name=”trait.pdf”
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=trait.pdf
JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9G
bGF0ZURlY29kZSA+PgpzdHJlYW0KeAGdkDsLwzAMhHf/iuvbHurYjvLw2tKlW0Bb0ynQoZAh5P9D
laSBli6hGOGzZD5x16FCh+TcezQ93Hj6RlrOBpreg/ABWRltDGhanBjZ9FOuIEWRwK1KmAM8+AG9
MuAnLjzSF6OK0sbUFQNPcYsP3vovXpTNKdEv7wa92RrxSNA7g6OzXjqyZFL7UcjsMItaG9zBV7Gk
hsCWWiIqbMiz/B3RtyU1R1S9AC/yTvwKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjE3MwplbmRv
[BIG CHUNK REMOVED FOR BREVITY]
MzgyYzE5NDFkZmU1NTRmMWQ1YTA3YjE3MT4KPDA1MjI3YjAzODJjMTk0MWRmZTU1NGYxZDVhMDdi
MTcxPiBdID4+CnN0YXJ0eHJlZgoxMzQzMwolJUVPRgo=
–b1_jJbWaSTAkopK9vM6vR9GTUaEFzNPIcbXXAiO2detU–
——-
Here is my code:
$email->setFrom(‘grains.testing@vt.edu’);
$email->Subject=’need dynamic: corn or silage’;
$email->isHTML(true);
$email->Body = ‘this is the body of the email’;
$email->addAddress(‘sarah@example.com’);
$email->AddAttachment(‘Document1.pdf’, $name = ‘trait.pdf’, $encoding = ‘base64’, $type = ‘application/pdf’);
$email->send();
Hi Sarah,
sorry for my late reply.
It seems like an encoding issue. Also, there is probably something wrong in the addAttachment syntax. It should be like this:
$email->addAttachment(“/path/to/file.pdf”, “trait.pdf”, “base64”, “application/pdf”);
Could you please try again and see if it works?
Thanks.
Alex webdevelop, nope, more like Alex GOD thank you so much!
Bonjour.
Tout d’abord, merci pour ce tutoriel, il est très explicite. Toutefois, je rencontre un problème. Voilà, j’aimerai recevoir les mails envoyés depuis mon site internet directement vers ma messagerie Gmail. Pour cela j’ai choisis l’authentification par la vérification en deux étapes de gmail, en générant un mot de passe d’applications.
Après essai, je ne reçois pas de mail sur ma boîte mail. Je partage mon code. Peut-être ai-je oublié quelque chose. Faut-il que le site soit héberger pour que cela fonctionne ? Pour le moment j’utilise un serveur externe pour afficher les données. Mon site n’est pas encore en ligne. Voici le code du fichier php :
isSMTP();
$mail->HOST = ‘smtp.gmail.com’;
$mail->SMTPAuth = true;
$mail->SMTPSecure = ‘tls’;
$mail->Username = ‘ici mon adresse mail’;
$mail->Password = ‘ici mdp application’;
$mail->Port = 587;
$mail->setFrom($_POST[’email’], $_POST[‘nom’]);
$mail->addAddress(‘ici mon adresse mail’, ‘mon nom’);
$mail->Subject = ‘Email de mon site web’;
$mail->Body = $_POST[‘message’];
$mail->send();
if (!$mail->send()) {
echo “Erreur lors de l’envoi du message” . $mail->ErrorInfo();
} else {
echo “Votre message a bien été envoyé.”;
}
}
?>
Hi Karima,
the code seems fine, even for Google. As a start, I suggest you set the SMTP debug output like this:
$mail->SMTPDebug = 4;
If something goes wrong, you should now see a debug message printed from $mail->ErrorInfo
Also, note that it’s ErrorInfo and not ErrorInfo().
Let me know how it goes.
How do I use this in a function and just include the classes needed ?
I want to add the line below in my code where needed to send a mail
Also I wont be using composer as I am on sharedhosting
include(‘some class or function’);
function mySendMail($to, $from, $subject, $message);
Hi Dieter,
you can include the classes and set the namespaces like this:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require ‘C:\PHPMailer\src\Exception.php’;
require ‘C:\PHPMailer\src\PHPMailer.php’;
require ‘C:\PHPMailer\src\SMTP.php’;
All the details are in the “Installing PHPMailer without Composer” chapter.
Let me know if you have any doubt.
Hello i attempted to send e-mail via phpmailer over gmail account, that works fine but when i attempt to use to other server i have 3 other mails the only answer is:
Fatal error: Maximum execution time of 30 seconds exceeded in D:\xampp\htdocs\MailDemo\vendor\phpmailer\phpmailer\src\SMTP.php on line 1125
What is bad?
Hi George,
the error may be caused by a connection timeout to the SMTP servers. Can you try connecting manually to the SMTP and see if it works?
You can also try to temporarily increase the script timeout to see if a more clear error arises.
You can do that with this statement:
set_time_limit(180);
(this will set the timeout to 3 minutes).
Let me know how it goes.
Hello the uppering the time limit does not helped, how is possible to manuály connect to smtp? via ping?
It’s better to try Putty (just search “putty” on Google and download it from the first result).
Insert the SMTP address or domain name and the port where to connect, then try connecting.
If you cannot connect and you get a timeout, it may be the cause of the PHPMailer error.
Keep me posted.
Hi Alex i had to use unsecured connection, but seems it works, thank You very much
hi…
Thanks for this tutorial.when i click the send button,it shows a blank document and nothing shows in the page.i am developed without using composer.
//here is my code
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require ‘C:\Users\Downloads\PHPMailer\src\Exception.php’;
require ‘C:\Users\Downloads\PHPMailer\src\PHPMailer.php’;
require ‘C:\Users\Downloads\PHPMailer\src\SMTP.php’;
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom(‘myname@gmail.com’, ‘name’);//sender
$mail->addAddress(‘receiver@gmail.com’, ‘receipient’);//receiver
$mail->Subject = ‘Test’;
$mail->Body = ‘customer deatails.’;
$mail->isSMTP();//use smtp
$mail->Host = ‘smtp.gmail.com’;//smtp server address
$mail->Port = 587;//smtp port
$mail->SMTPAuth = TRUE;//smtp authentication
$mail->SMTPSecure = ‘tls’;//encryption
$mail->Username = ‘smtp@gmail.com’;//smtp authentication username
$mail->Password = ‘password’;//smtp authentication password
$mail->send();
}
catch (Exception $e)
{
echo $e->errorMessage();
}
catch (\Exception $e)
{
echo $e->getMessage();
}
Hi Ajo,
try adding this before the send():
$mail->SMTPDebug = 4;
This should make the Exception print the error message. Let me know if it works for you.
How can i get better sender ?
Hi alex
I got some problem in my code that easily a email verification but there are problem here are the prompt error…
Fatal error: Uncaught PHPMailer\PHPMailer\Exception: Could not instantiate mail function. in C:\xampp\PHPMailer\src\PHPMailer.php:1785 Stack trace: #0 C:\xampp\PHPMailer\src\PHPMailer.php(1583): PHPMailer\PHPMailer\PHPMailer->mailSend(‘Date: Thu, 24 O…’, ‘\r\n …’) #1 C:\xampp\PHPMailer\src\PHPMailer.php(1417): PHPMailer\PHPMailer\PHPMailer->postSend() #2 C:\xampp\htdocs\OCT16Latest\register.php(53): PHPMailer\PHPMailer\PHPMailer->send() #3 {main} thrown in C:\xampp\PHPMailer\src\PHPMailer.php on line 1785
i don’t know how to fix it. here my code…
//PHPMailer Process
$mail = new PHPMailer(TRUE);
$mail->setFrom(‘hello@codingpassiveincome.com’);
$mail->addAddress($email,$username);
$mail->Subject =”Please verify Email!”;
$mail->isHTML(true);
$mail->Body =”Click Here“;
if(!$mail->send()){
$msg = “You have been Registered! Please verify your Email “;
}
else{
$msg = “Something wrong has happened! Please try again!”;
}
Hi Christian,
that error is usually caused by PHPMailer trying to use the PHP default mail() function (because you didn’t set an SMTP server).
Are you under a Windows local development environment?
i wanted to send database data via email
Any help?
Hi, sure you can. What kind of data, exactly?
Can u provide info abt how to configure the same with laravel (in controller and in env files) with same smtp.google server, cuz many people have the issue regarding the same,with google 2-factore and without. plz it would be so helpful.
Hi Alex,
Good article, easy to read and understand. However, not technical at all, looking for robust configuration for my small business. Have registered G-Suite, and dedicated virtual private server (CentOs with Hyper-V) running our OpenCart online store. Have dedicated email for online orders (myorder@) but the hosting company sometimes trash the connectivity to G-Suite. VPS server configured for remote mail, and corresponding MX records setup as per Google instructions. Would like to use to configure G-Suite for smtp-relay.gmail.com instead (https://support.google.com/a/answer/2956491), and configure the server to send email via Google that way instead, still using the notion of noreply@ instead, with shared email box as reply to. Is this scenario do-able, and what would need to be configured where to enable?
Hi Ockert,
I think that you can keep your own domain, including your email addresses, and just configure your VPS mail server to use the G-Suite SMTP relay.
I don’t think you can use PHPMailer for this. You need to configure the Mail Server itself (Postfix, qMail etc.)
Alex, Amazingly Great job. These two points are well covered; ” Installing Composer and PHPMailer on Windows ” and “Installing PHPMailer without Composer”. Thanks for sharing this info. The best part is the article has all the practical detailing! Keep sharing
Thank you Maria, nice to know my tutorial has been helpful 🙂
Hi. After phpmailer send is successful, by default, it echos a reall reall long message. Now due to the way im working with phpmailer, this long text is displayed to my frontend. How can i modify the success message? Or block it maybe?
Hi Roy,
maybe you are echoing the Debug messages?
Thank for this tutorial
Thank you for your comment, Michael.
hello,
I’ve tried to run in the command window the phpMailer
with the command : “cd C:\xampp\composer”
and it doesn’t work. It says: “the system cannot find the path specified”.
What can I do?
Thank you.
Hi,
the error means the C:\xampp\composer directory doesn’t exist. You can simply create it from the File Explorer, then go back to the command prompt and try again.
Let me know if it works.
Really Helpful Content For Me. I Need More This Kind Of Content.
thanks so much
this is the error which im getting…
12019-08-29 07:10:00 CLIENT -> SERVER: EHLO localhost
2019-08-29 07:10:00 CLIENT -> SERVER: STARTTLS
2019-08-29 07:10:01 CLIENT -> SERVER: EHLO localhost
2019-08-29 07:10:01 CLIENT -> SERVER: AUTH LOGIN
2019-08-29 07:10:01 CLIENT -> SERVER: <credentials hidden>
2019-08-29 07:10:02 CLIENT -> SERVER: <credentials hidden>
2019-08-29 07:10:02 SMTP ERROR: Password command failed: 535-5.7.8 Username and Password not accepted. Learn more at535 5.7.8 https://support.google.com/mail/?p=BadCredentials bt18sm1287449pjb.1 – gsmtp
SMTP Error: Could not authenticate.
2019-08-29 07:10:02 CLIENT -> SERVER: QUIT
SMTP Error: Could not authenticate.
Fatal error: Uncaught exception ‘PHPMailer\PHPMailer\Exception’ with message ‘SMTP Error: Could not authenticate.’ in C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php:1960
Stack trace:
#0 C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php(1774): PHPMailer\PHPMailer\PHPMailer->smtpConnect(Array)
#1 C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php(1516): PHPMailer\PHPMailer\PHPMailer->smtpSend(‘Date: Thu, 29 A…’, ‘<p><a href=’htt…’)
#2 C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php(1352): PHPMailer\PHPMailer\PHPMailer->postSend()
#3 C:\xampp\htdocs\paydocs_ui\ajax\ajaxSendForgotPswd.php(64): PHPMailer\PHPMailer\PHPMailer->send()
#4 {main}
thrown in C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php on line 1960
and below is my code:
$message = “http://35.154.232.47/paydocs/“;
//$message .= ‘Thank you.’;
require “../vendor/autoload.php”;
//require ‘../PHPMailer/PHPMailerAutoload.php’;
// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
//Server settings
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = ‘smtp.gmail.com’; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = ‘mygmailid@gmail.com’; // SMTP username
$mail->Password = ‘mypassword’; // SMTP password
$mail->SMTPSecure = ‘tls’; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
//Recipients
$mail->setFrom(‘itd.gpa@gmail.com’, ‘paydocs’);
$mail->addAddress($username); // Add a recipient
//$mail->addReplyTo(‘xxxx@gmail.com’);
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = “Password Reset”;
$mail->Body = $message;
$mail->CharSet=”utf-8″;
if(!$mail->send())
{
echo ‘Mailer Error: ‘ . $mail->ErrorInfo;
}
else
{
echo ‘Mail Sent Successfully…!’;
}
Do you have Google 2-step verification enabled?
no
how to do that can you explain please..
thanks.
hi alex i have tried with 2-step verification and i kept that 16 digit string in my password place. saved and sun the code on my local host. but it still shows this error..
12019-08-29 11:18:26 SERVER -> CLIENT: 220 smtp.gmail.com ESMTP y14sm6640466pfq.85 – gsmtp
2019-08-29 11:18:26 CLIENT -> SERVER: EHLO localhost
2019-08-29 11:18:26 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [103.5.16.112]250-SIZE 35882577250-8BITMIME250-STARTTLS250-ENHANCEDSTATUSCODES250-PIPELINING250 SMTPUTF8
2019-08-29 11:18:26 CLIENT -> SERVER: STARTTLS
2019-08-29 11:18:26 SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
SMTP Error: Could not connect to SMTP host.
2019-08-29 11:18:26 CLIENT -> SERVER: QUIT
2019-08-29 11:18:26 SERVER -> CLIENT:
2019-08-29 11:18:26 SMTP ERROR: QUIT command failed:
SMTP Error: Could not connect to SMTP host.
Fatal error: Uncaught exception ‘PHPMailer\PHPMailer\Exception’ with message ‘SMTP Error: Could not connect to SMTP host.’ in C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php:1947
Stack trace:
#0 C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php(1774): PHPMailer\PHPMailer\PHPMailer->smtpConnect(Array)
#1 C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php(1516): PHPMailer\PHPMailer\PHPMailer->smtpSend(‘Date: Thu, 29 A…’, ‘<p><a href=’htt…’)
#2 C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php(1352): PHPMailer\PHPMailer\PHPMailer->postSend()
#3 C:\xampp\htdocs\paydocs_ui\ajax\ajaxSendForgotPswd.php(63): PHPMailer\PHPMailer\PHPMailer->send()
#4 {main}
thrown in C:\xampp\htdocs\paydocs_ui\vendor\phpmailer\phpmailer\src\PHPMailer.php on line 1947
In reply to Anonymous.
Please join my FB group because this is taking a bit too long for the comments section here.
Here’s the link: https://www.facebook.com/groups/289777711557686/
I have tried steps you tell…but i am getting an error…
“Could not instantiate mail function.”
please help me to solve this .
thank you….
Hi,
that usually means PHPMailer is trying to rely on the default system MTA (instead of using an SMTP server directly) but it cannot find any.
An MTA is a mail program for mail delivery, like Sendmail. The default PHP mail() function uses it, and PHPMailer does too if it’s set not to use an SMTP direct connection.
Maybe you do not have any MTA (like Sendmail) installed?
Also, I think that PHPMailer cannot work with an MTA under Windows, or at least it needs some tweaking. Are you under Windows or Linux?
i am under windows
Thanks for your reply.
Can you try using an SMTP configuration and see if it works?
works on centos 7, but not working on windows with openserver
Hi Akmal,
do you get any error message from PHP or from the SMTP server?