PHPMailer is a code library to send emails safely and easily via PHP code from a web server, and you can also send emails from localhost.
Here you will learn how to send emails using PHPMailer with Gmail SMTP and for authentication, we will use email
and password
and we will also see an example with the XOAUTH2 mechanism.
Sending emails using PHPMailer with “Email” and “Password”
Generate app password
First, you have to generate an App password for your Gmail.
So, log in to your Google account » Go to the security tab » Make sure that 2-step verification is enabled.

Now, open the following link (make sure you are logged in), and generate an app password.
https://myaccount.google.com/apppasswords


App password has been generated, copy the password –

After that, Install only the PHPMailer via composer on your project folder –
composer require phpmailer/phpmailer
Here is an example of how to use the PHPMailer to send emails with the Username and Password. Want to know more, read the official docs.
In the following code, change the details according to yours –
<?php
require __DIR__ . "/vendor/autoload.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
// Change the following details according to yours
$gmail = "[email protected]";
$app_password = "app_password";
$sender_name = "Sender Name";
$receiver_email = "[email protected]";
$mail_subject = "email subject";
$mail_body = "email body";
try {
//Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
$mail->isSMTP(); //Send using SMTP
//Enable SMTP debugging
//SMTP::DEBUG_OFF = off (for production use)
//SMTP::DEBUG_CLIENT = client messages
//SMTP::DEBUG_SERVER = client and server messages
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->Host = 'smtp.gmail.com'; //Set the SMTP server to send through
//TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth = true; //Whether to use SMTP authentication
$mail->Username = $gmail; //SMTP username
$mail->Password = $app_password; //SMTP password
/** Set who the message is to be sent from
* For gmail, this generally needs to be the same as the user you logged * in as. */
$mail->setFrom($gmail, $sender_name);
// who will receive the email
$mail->addAddress($receiver_email);
// if you want to send email to multiple users, then add the email addresses you which you want to send.
//$mail->addAddress('[email protected]');
//$mail->addAddress('[email protected]');
$mail->isHTML(true);
$mail->Subject = $mail_subject; // Subject of the Email
$mail->Body = $mail_body; // Mail Body
//For Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // You can specify the file name
$mail->send();
echo "Email has been sent successfully.";
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
Sending emails using PHPMailer with “XOAUTH2”
1. Create a folder inside the localhost directory, and name it whatever you want, I called it 📁 phpmailer.
2. Install the phpmailer
and oauth2-google
via composer inside the phpmailer directory.
composer require phpmailer/phpmailer league/oauth2-google
3. Move the get_oauth_token.php
to the root of the phpmailer folder.


#from this
phpmailer/vendor/phpmailer/phpmailer/get_oauth_token.php
#to this
phpmailer/get_oauth_token.php
How to get Google Client ID and Secret for PHPMailer?
oauth2-google
will not work without the client ID, Secret, and refresh token, so we have to generate these three things. Follow the below steps to generate the Client ID and Secret –
- Login to Google Cloud Console
Go to the Google Cloud Console and login with your Google account.
- Create a New Project
After login to your account, Go to Select a project » New Project » create a new project.
- Select the project and go to the APIs & Services
- Enable the Gmail API
- Create Credentials
- Choose Web Application & enter the redirect URL
Redirect URL will be the location of the
get_oauth_token.php
- Collect your Client ID and Secret
- Get your Refresh Token
Open the get_oauth_token.php in your browser, then add client ID and Secret and then click continue.
http://localhost/phpmailer/get_oauth_token.php
4. After getting the Client-ID, Client-Secret, and refresh token, here is the PHP code to send emails –
<?php
// Add your Client ID, Secret and Refresh token
$clientID = "654563609574-7f5a4c2ev************99m0i1.apps.googleusercontent.com";
$clientSecret = "GOCSPX-opn_K************NLMPB";
$refreshToken = "1//0g8Dng2fJk3AuC********NwF-L9IrQVKMzy6t***********sVCDSDEYCW2j8z*****nTYiXO3VzuthW-cico";
$email = '[email protected]';
$receiver_email = '[email protected]'; // Email-address of the recipient of the email
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\OAuth;
use League\OAuth2\Client\Provider\Google;
// Load Composer's autoloader
require 'vendor/autoload.php';
// Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
try{
$mail->isSMTP(); // Tell PHPMailer to use SMTP
// Enable SMTP debugging
/**
* SMTP::DEBUG_OFF -> off (for production use)
* SMTP::DEBUG_CLIENT -> client messages
* SMTP::DEBUG_SERVER -> client and server messages
*/
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
// Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';
// Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;
// Set the encryption mechanism to use - STARTTLS or SMTPS
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
// Whether to use SMTP authentication
$mail->SMTPAuth = true;
// Set AuthType to use XOAUTH2
$mail->AuthType = 'XOAUTH2';
// Create a new OAuth2 provider instance
$provider = new Google(
[
"clientId" => $clientID,
"clientSecret" => $clientSecret,
]
);
// Pass the OAuth provider instance to PHPMailer
$mail->setOAuth(
new OAuth(
[
"provider" => $provider,
"clientId" => $clientID,
"clientSecret" => $clientSecret,
"refreshToken" => $refreshToken,
"userName" => $email,
]
)
);
/*
* Set who the message is to be sent from
* For gmail, this generally needs to be the same as the user you logged in as
*/
$mail->setFrom($email, 'Name of the sender');
$mail->addAddress($receiver_email);
/* if you want to send email to multiple users, then add the email addresses you which you want to send. e.g -
* $mail->addAddress('[email protected]');
* $mail->addAddress('[email protected]');
*/
$mail->isHTML(true); # Set email format to HTML
$mail->Subject = "Subject Of the email";
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
/*
* For Attachments -
* $mail->addAttachment('/var/tmp/file.tar.gz'); Add attachments
* $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); You can specify the file name in the second parameter
*/
// Call the send() method to send the mail.
$mail->send();
echo 'Message has been sent';
}
catch(Exception $e){
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
Send emails using PHPMailer with HTML Form
Now we will see how to send emails using PHPMailer with HTML Form. Here is the Demo –

In the same project folder (phpmailer) we have to make three files – send.php
, index.php
, and style.css

send.php
file contains the send_mail()
function used to send emails, this function has one parameter ($form_data
) and takes form data as an array.
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\OAuth;
use League\OAuth2\Client\Provider\Google;
require_once __DIR__ . "/vendor/autoload.php";
function send_mail($form_data)
{
// Put your client id, secret, refresh token, and email
$clientID = "654563609574-7f5a*****oj0bt**0i1.apps.googleusercontent.com";
$clientSecret = "GOCSPX-opn_K*********KNLMPB";
$refreshToken = "1//0g8Dng2fJk3AuCgY*****GBASNwF-L9IrQV********LbUp6lDVatPsVCD*****TYiXO3VzuthW-cico";
$sender_email = "[email protected]";
$provider = new Google(
[
"clientId" => $clientID,
"clientSecret" => $clientSecret,
]
);
$oAuth = new OAuth(
[
'provider' => $provider,
'clientId' => $clientID,
'clientSecret' => $clientSecret,
'refreshToken' => $refreshToken,
'userName' => $sender_email,
]
);
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->SMTPDebug = SMTP::DEBUG_OFF;
$mail->Host = 'smtp.gmail.com';
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth = true;
$mail->AuthType = 'XOAUTH2';
$mail->setOAuth($oAuth);
$mail->setFrom($sender_email, "Sender Name");
$mail->addAddress($form_data["email"]);
$mail->isHTML(true);
$mail->Subject = $form_data["subject"];
$mail->Body = $form_data["message"];
// If there is any attachment to send
if ($form_data["atch"]) {
$mail->addAttachment($form_data["atch"]["tmp_name"], $form_data["atch"]["name"]);
}
$mail->send();
return true;
} catch (Exception $e) {
return false;
}
}
index.php
contains the HTML form and here we will call the send_mail()
function to send email, Other than it contains some validations –
<?php
require_once __DIR__ . "/send.php";
// This variables are for showing messages
$error = false;
$success = false;
if (
isset($_POST["email"]) &&
isset($_POST["subject"]) &&
isset($_POST["message"]) &&
isset($_FILES["attachment"])
) {
$email = trim($_POST["email"]);
$subject = trim($_POST["subject"]);
$message = trim($_POST["message"]);
$file = $_FILES["attachment"];
// Email Validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Invalid Email address";
}
// If there is no attachment to send then set the $file = false;
if ($file["error"] === 4) {
$file = false;
}
// Chekcing File size max 25MB
if ($file && ($file["error"] === 1 || $file["size"] > 1048576 * 25)) {
$error = "File is too large Max 25MB";
}
// If there is no error then cll the sen_mail() function
if ($error === false) {
$form_data = [
"email" => $email,
"subject" => $subject,
"message" => $message,
"atch" => $file
];
$result = send_mail($form_data);
if ($result) {
$success = "Email has been sent.";
} else {
$error = "Email could not be delivered";
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PHPMailer Send Emails</title>
<link href="./style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>PHPMailer Send Emails</h1>
<form action="" method="POST" enctype="multipart/form-data">
<label for="email">To:</label>
<input type="email" name="email" id="email" autocomplete="off" placeholder="Email address" />
<label for="subject">Subject:</label>
<input type="text" name="subject" id="subject" autocomplete="off" placeholder="Subject">
<label for="message">Message:</label>
<textarea name="message" id="message" placeholder="Message"></textarea>
<label for="attachment">Attachment: (Max 25MB)</label>
<input type="file" name="attachment" id="attachment">
<?php echo ($success) ? '<div class="message">' . $success . '</div>' : ''; ?>
<?php echo ($error) ? '<div class="message error">' . $error . '</div>' : ''; ?>
<button type="submit">Send</button>
</form>
</div>
<script>
// this js code stops the multiple form submission on page refresh
if (window.history.replaceState) {
window.history.replaceState(null, null, window.location.href);
}
</script>
</body>
</html>
style.css
contains the stylesheet for the HTML Form –
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap');
*{
box-sizing: border-box;
}
:root{
--main-color:#7A3653;
}
html{
font-size: 16px;
}
body{
font-family: 'Open Sans', sans-serif;
background:#f7f7f7;
}
h1{
text-align: center;
margin-bottom: 0;
}
form{
display: flex;
flex-direction: column;
max-width: 500px;
margin: 0 auto;
padding: 20px;
}
button,input,textarea{
font-family: 'Open Sans', sans-serif;
font-size: 1rem;
padding: 10px;
}
button[type="submit"],
input,textarea{
border: 1px solid rgba(0, 0, 0, .3);
border-radius: 3px;
outline: none;
}
textarea{
resize: vertical;
min-height: 120px;
}
input:is(:hover,:focus),
textarea:is(:hover,:focus){
border-color: var(--main-color);
}
button[type="submit"]{
background: var(--main-color);
color: white;
cursor: pointer;
font-weight: 700;
margin-top: 15px;
}
button[type="submit"]:hover{
outline:var(--main-color) solid 2px;
outline-offset: 2px;
}
label{
font-weight: 700;
margin: 10px 0 3px 0;
}
.message{
border: 2px solid #4BB543;
border-radius: 3px;
background: hsl(116, 46%, 90%);
margin-top: 15px;
padding: 10px;
}
.error{
border-color: #ff3333;
background: hsl(0, 100%, 90%);
}