Laravel & Php

How to use PHPMailer


phpmailer

When it comes to adding email functionality to your PHP app, PHPMailer class is the winning option. It is compatible with most of the PHP frameworks (Laravel or Symfony are based on the SwiftMailer library, though, but it is still possible to use PHPMailer as well.) PHPMailer provides powerful functionality to create HTML emails with attachments and send them to multiple recipients via SMTP or a local webserver. Learn how to easily use all these options in this tutorial!

What is PHPMailer

PHPMailer is the classic email sending library for PHP. It supports several ways of sending email messages, such as mail(), Sendmail, qmail, and direct dispatch to SMTP servers. In addition, it provides numerous advanced features:

  • SMTP authentication
  • secure/MIME encryption
  • support of TLS and SSL protocols
  • HTML content along with plain text
  • multiple fs, string, and binary attachments
  • embedded images support

Sending Email With PHPMailer and SMTP

To send emails with PHPMailer and SMTP, you need to install PHPMailer and configure SMTP settings first.

How to install PHPMailer

Up to version 5, PHPMailer was providing “PHPMailerAutoload.php” file, so all that was needed was to include it in your script and create a PHPMailer instance. Starting from PHPMailer 6.0, released in August 2017, you need to install it, preferably via Composer, a dependency manager for PHP (this way is recommended by PHPMailer’s creators on Github). After installing Composer, add this line to your composer.json file:

"phpmailer/phpmailer": "~6.1"

or run

composer require phpmailer/phpmailer

If you don’t want to install Composer, for example, while working within a testing environment, you can add PHPMailer manually. Download files with PHPMailer source code, then copy the contents of the PHPMailer folder to one of the include_path directories specified in your PHP configuration, and load each class file manually:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'path/to/PHPMailer/src/Exception.php';
require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';

Adding Exception class will help you handle errors and debug them. In PHP it works similarly to other programming languages. So, without it, if there is an error in your email sending code, you will just see a message saying Exception class is not found, but you won’t be provided with any details on how to debug it. We will describe debugging in a separate section of this post.

SMTP configuration

For PHPMailer to be able to send emails from your PHP app, you will need to connect it to an SMTP server.

We suggest you first use an email testing tool such as Mailtrap Email Testing and its SMTP server to test the functionality before sending anything to real recipients. Once you make sure that things are working properly and your emails look right, you can easily substitute Email Testing SMTP settings with the settings of your real server.

Besides providing you with SMTP settings, Email Testing also allows you to preview, inspect and debug emails in staging. This way, you can fix any errors before the sending is done and not risk spamming real recipients with test emails. 

The most notable features of this testing tool include spam checking, HTML/CSS validation, blacklist reports, and more.

To start using Mailtrap Email Testing, create a free account, go to Email Testing-> Inboxes, and copy-paste the provided SMTP settings to your PHPMailer script:

$phpmailer = new PHPMailer();
$phpmailer->isSMTP();
$phpmailer->Host = 'sandbox.smtp.mailtrap.io';
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 2525;
$phpmailer->Username = '07f4dbf61b8122';
$phpmailer->Password = 'd7fc5d57bc6eac';

There is one more point left to mention about SMTP: POP-before-SMTP for authentication. This method is almost fully replaced by the SMTP authentication but still can be used sometimes. Its main advantage is the transparency for the user who is sending an email. Check this Github page to get the example of using POP-before-SMTP with PHPMailer.

Sending HTML email via SMTP with PHPMailer

You will most likely use HTML to design your email notification. So, let’s review some examples of using HTML methods and attributes.

Basic HTML message

If you have used Composer for installation, include the Composer generated autoload.php file:

require 'path/to/composer/vendor/autoload.php';

If you have installed PHPMailer manually, initialize it like this:

require path/to/PHPMailer/src/PHPMailer.php';
require path/to/PHPMailer/src/SMTP.php';
require path/to/PHPMailer/src/Exception.php';

Then create the PHPMailer class:

<?php
use PHPMailer\PHPMailer\PHPMailer;

The next step is to create a new PHPMailer object:

$mail = new PHPMailer();

Now let’s move to an SMTP configuration:

$mail->isSMTP();
$mail->Host = 'sandbox.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g'; //paste one generated by Mailtrap
$mail->Password = '1a2b3c4d5e6f7g' //paste one generated by Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;

Specify PHPMailer headers:

$mail->setFrom('info@mailtrap.io', 'Mailtrap');
$mail->addReplyTo('info@mailtrap.io', 'Mailtrap');
$mail->addAddress('recipient1@mailtrap.io', 'Tim');
$mail->addCC('cc1@example.com', 'Elena');
$mail->addBCC('bcc1@example.com', 'Alex');

If you need to add several addresses, specify each of them as a new command:

$mail->AddBCC('bcc2@example.com', 'Anna');
$mail->AddBCC('bcc3@example.com', 'Mark');

With PHPMailer, you can loop your message and send it to multiple recipients. In particular, you can read a list from the table. We will review such examples a bit later in this post, and now let’s get back to our basic message. 

Set a subject:

$mail->Subject = 'Test Email via Mailtrap SMTP using PHPMailer';

Then set the email format to HTML with isHTML(true) property:

$mail->isHTML(true);

Now you can input the desired content:

$mailContent = "<h1>Send HTML Email using SMTP in PHP</h1>
    <p>This is a test email I’m sending using SMTP mail server with PHPMailer.</p>";
$mail->Body = $mailContent;

With PHPMailer, you can also make a nice HTML email, with custom formatting, images, and send emails with attachments. For your convenience, PHPMailer provides an option to read an HTML message body from an external file, convert referenced images to embedded as well as convert HTML into a basic plain-text alternative body. This way, you will not overload your message sending code with HTML and will be able to update your HTML template independently. To include a separate HTML file, add these attributes:

$mail->msgHTML(file_get_contents('contents.html'), __DIR__);

In the end, specify the email sending attributes:

if($mail->send()){
    echo 'Message has been sent';
}else{
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
}

The result “Message has been sent” informs you that your code was executed correctly.

Since you used Mailtrap Email Testing’s SMTP settings, you can then go to Email Testing-> Inboxes to check what your HTML email looks like.

HTML email with attachments

There are two options for adding files to your message: 

  • Enclose a file from your filesystem – like you can make it in the email client. In this case, your files should be saved in the same directory as the script.
    • Also, a file can be inlined into your message, this is valid for images.
  • Add a string attachment –  in this case, the data stored in a variable is attached to the message. It can be extracted from a database, for example, so you don’t need to save it as a file. 

To attach a file, you just need to specify its path. Also, you can add a filename but it’s optional: the script will use the actual name of your file:

$mail->addAttachment('path/to/invoice1.pdf', 'invoice1.pdf');

To add another file, repeat the command:

$mail->addAttachment('path/to/calculation1.xlsx', 'calculation1.xlsx');

To add an attachment from the string, use addStringAttachment() command. You should pass the content and the filename:

$mysql_data = $mysql_row['blob_data'];
$mail->addStringAttachment($mysql_data, 'db_data.db'); 

This is an example of adding data stored as a BLOB (Binary Large OBject) from MySQL database.

Alternatively, you can use a remote URL, like below:

$mail->addStringAttachment(file_get_contents($url), 'myfile.pdf');

To embed an image, we use CID attachments here:

$mail->addEmbeddedImage('path/to/image_file.jpg', 'image_cid');
$mail->isHTML(true);
$mail->Body = '<img src="cid:image_cid">';

Finally, let’s review an example of a whole message with an inlined image and internal HTML body:

<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'path/to/composer/vendor/autoload.php';
$mail->isSMTP();
$mail->Host = 'sandbox.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'paste one generated by Mailtrap';
$mail->Password = 'paste one generated by Mailtrap’
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;
$mail->setFrom('from@example.com', 'First Last');
$mail->addReplyTo('towho@example.com', 'John Doe';
$mail->isHTML(true);
$mail->Subject = "PHPMailer SMTP test";
$mail->addEmbeddedImage('path/to/image_file.jpg', 'image_cid');
$mail->Body = '<img src="cid:image_cid"> Mail body in HTML';
$mail->AltBody = 'This is the plain text version of the email content';
if(!$mail->send()){
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
}else{
    echo 'Message has been sent';

The result “Message has been sent” informs you that your code is executing correctly. To check the delivery result and details, go to your Mailtrap inbox: your messages will get there in seconds.

Sending emails to multiple recipients

Above, we have examined how to send one and the same email to several recipients, including CCing and BCCing. What if you need to send a modified message to a list of recipients, which is often required for transactional emails? PHPMailer offers features for such use cases as well!

<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'path/to/composer/vendor/autoload.php';
$mail = new PHPMailer;
$body = file_get_contents('contents.html');
$mail->isSMTP();
$mail->Host = 'sandbox.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g'; //generated by Mailtrap
$mail->Password = '1a2b3c4d5e6f7g'; //generated by Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;
$mail->SMTPKeepAlive = true; // add it to keep SMTP connection open after each email sent
$mail->setFrom('list@example.com', 'List manager');
$mail->Subject = "New Mailtrap mailing list";
$users = [
  ['email' => 'max@example.com', 'name' => 'Max'],
  ['email' => 'box@example.com', 'name' => 'Bob']
];
foreach ($users as $user) {
  $mail->addAddress($user['email'], $user['name']);
  $mail->Body = "<h2>Hello, {$user['name']}!</h2> <p>How are you?</p>";
  $mail->AltBody = "Hello, {$user['name']}! \n How are you?";
  try {
      $mail->send();
      echo "Message sent to: ({$user['email']}) {$mail->ErrorInfo}\n";
  } catch (Exception $e) {
      echo "Mailer Error ({$user['email']}) {$mail->ErrorInfo}\n";
  }
  $mail->clearAddresses();
}
$mail->smtpClose();

How to use PHPMailer with Gmail SMTP

Gmail is one of the most popular SMTP servers, which allows you to send emails for free. 

Prior to May 30, 2022, from your Google account security settings “Less secure app access” had to be turned on to send emails using PHPMailer. Since the “Less secure apps” feature that allows third-party software and devices to sign in to your Gmail account is no longer supported by Google you can choose the other more secure options available.  However, it does require some tinkering with authentication settings.

Send an email with PHPMailer without SMTP server

An SMTP transport option is the most popular and usable with PHPMailer. However, as we’ve already mentioned, it supports other ways as well. 

For localhost, you can use the standard Sendmail program:

// Set mailer with this method
$mailer->isSendmail();
// And send mail as usual
$mailer->send();

If you prefer Unix, then use qmail:

// Set mailer with this method
$mailer->isQmail();
// And send mail as usual
$mailer->send();

PHPMailer Laravel PHP
Share with Friends

Like this chef? Share with friends..