What is PHPMailer and how do you use it to send test emails via SMTP in PHP? Find out this and more on email testing in PHP here.
How to organize email testing in PHP
PHP is one of the most popular languages for web development, so it’s no wonder that email sending and testing in PHP is a topic full of questions. Especially since the standard PHP built-in function for email sending, mail(), provides limited capabilities when it comes to email creation and sending.
When using PHP’s standard email sending function, you can’t really add attachments or embed images to your emails, nor you can’t build HTML email templates that really bring the look of an email to the next level. Besides, security concerns occur when using mail() because emails are sent from your web server instead of an SMTP one, which poses a risk of your email address getting blacklisted.
But there’s a safe and secure solution. You can use an alternative to the standard PHP function — external mail packages, such as the PHPMailer class. So let’s break down how it works.
What is PHPMailer?
PHPMailer is a library for PHP developed to send emails. It has become a go-to library because of its versatility — you can use it to send emails via Sendmail, qmail, and mail(), as well as it allows dispatching to SMTP servers directly.
PHPMailer provides a range of features, like SMTP authentication, MIME encryption, image embedding, and attachments of various types, including binary, string, and fs ones. It also supports HTML content and SSL and TLS protocols.
Sending an Email With PHPMailer and SMTP
The first step to sending emails with PHPMailer is installing the library and configuring the SMTP settings. So how do you do that?
If you’re going to use PHPMailer version 5.0 or older, you can include the “PHPMailerAutoload.php” file the vendor provides in your script and create a PHPMailer instance to install it.
For versions 6.0 and later, PHPMailer’s creators recommend installing it via Composer. So after you’ve installed Composer, run:
composer require phpmailer/phpmailer
Or add the following line to your composer.json file:
"phpmailer/phpmailer": "~6.1"
You can also install PHPMailer manually if you need to, like if you’re working with a test environment. To do this, perform the following steps:
- Download files with the PHPMailer source code
- Copy the PHPMailer folder contents to the include_path directory defined in your configuration of PHP
- Load each class file manually via the following:
<?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';
Using the Exception class helps handle errors with ease: it will notify you in case of an error and direct on how to debug it. We’ll explain more about debugging later.
You can also go to the official documentation on Github to get more details on how to install PHPMailer.
Now that you have your PHPMailer installed, let’s discuss how you can send emails via SMTP using PHPMailer.
SMTP configuration
If you’re using the standard PHP mail() function, you can configure the SMTP settings in the “php.ini” file in your PHP installation folder. But keep in mind that since the PHP mail() function does not support SMTP authentication and email sending via external services, this will only work for localhost.
But what’s the solution then? As we’ve been discussing, PHPMailer enables SMTP authentication, so let’s configure your SMTP server setup to use the library.
To make sure you set up your PHPMailer right before you reach real customers’ inboxes, it’s best to use a fake SMTP server until you’re confident with switching to a real one. Mailtrap allows setting up an SMTP simulator, which is what we’re going to show you now.
If you haven’t used Mailtrap before, create a free account to get started. Now, go to your Inbox, then the SMTP settings tab and copy the following to your PHPMailer script:
server host ($mail->Host = ’smtp.mailtrap.io’) username ($mail->Username = ‘1a2b3c4d5e6f7g’ (example, generated by Mailtrap) password ($mail->Password = ‘1a2b3c4d5e6f7g’ (example, generated by Mailtrap) and port ($mail->Port = 25, or 465, or 2525
After you switch to a real SMTP server, you can replace the values in the example with those of your SMTP.
One last point ща SMTP configuration is authentication. While now SMTP authentication is the primary method used, POP-before-SMTP may be sometimes used, too, since it provides sender transparency. If you want to learn more about using POP-before-SMTP with PHPMailer, you can find it here.
Sending multiple emails
You can send emails to multiple recipients at once in PHP using the standard PHP mail() function. To do that, list the target recipients’ email addresses in $to = parameter and separate them with a comma. And this is the only way how you can send multiple emails via the native PHP mail() function.
While this method works, as we’ve already mentioned, this standard function provides limited functionality, like you can’t use templates or send really big email campaigns. That’s why sending bulk mail and looping them in PHP is more convenient if you use external mailing packages.
External mailing packages are basically plugins that you can install to extend the list of features you can access when using PHP. For example, you can use Mailgun Email API to send emails. But some of the go-to plugins for mass emailing are PHPMailer, Pear Mail, and Swift Mailer.
PHPMailer
As discussed earlier, PHPMailer is the most popular and often-chosen PHP library for sending emails. It allows for creating templates, including HTML and those really complex ones, adding attachments and images to the body of the email, and other features. PHPMailer validates emails automatically and is secure.
Here’s an example of what sending a booking confirmation email with PHPMailer would look like:
<?php // Start with PHPMailer class use PHPMailer\PHPMailer\PHPMailer; require_once './vendor/autoload.php'; // create a new object $mail = new PHPMailer(); // configure an SMTP $mail->isSMTP(); $mail->Host = 'smtp.mailtrap.io'; $mail->SMTPAuth = true; $mail->Username = '1a2b3c4d5e6f7g'; $mail->Password = '1a2b3c4d5e6f7g’; $mail->SMTPSecure = 'tls'; $mail->Port = 2525; $mail->setFrom('[email protected]', 'Your Hotel'); $mail->addAddress('[email protected]', 'Me'); $mail->Subject = 'Thanks for choosing Our Hotel!'; // Set HTML $mail->isHTML(TRUE); $mail->Body = '<html>Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.</html>'; $mail->AltBody = 'Hi there, we are happy to confirm your booking. Please check the document in the attachment.'; // add attachment $mail->addAttachment('//confirmations/yourbooking.pdf', 'yourbooking.pdf'); // send the message if(!$mail->send()){ echo 'Message could not be sent.'; echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Message has been sent'; }
As you can see, this example contains text, HTML, and an attachment, as well as it implies that the email is sent through an authenticated SMTP server.
Pear Mail
Pear Mail is a class providing several kinds of interfaces designed for email sending. Pear Mail is recommended in the official PHP documentation since it allows sending complex emails with HTML, embedding images, including attachments and sending emails through the standard mail() function in PHP.
You can also use other classes to access more features, such as the Mail_Queue class to create a queue for emails.
Here’s how the same booking confirmation email example would look when sent via Pear Mail:
require_once './vendor/autoload.php'; $from = 'Your Hotel <[email protected]>'; $to = 'Me <[email protected]>'; $subject = 'Thanks for choosing Our Hotel!'; $headers = ['From' => $from,'To' => $to, 'Subject' => $subject]; // include text and HTML versions $text = 'Hi there, we are happy to confirm your booking. Please check the document in the attachment.'; $html = 'Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.'; //add attachment $file = '/confirmations/yourbooking.pdf'; $mime = new Mail_mime(); $mime->setTXTBody($text); $mime->setHTMLBody($html); $mime->addAttachment($file, 'text/plain'); $body = $mime->get(); $headers = $mime->headers($headers); $host = 'smtp.mailtrap.io'; $username = '1a2b3c4g5f6g7e'; // generated by Mailtrap $password = '1a2b3c4g5f6g7e'; // generated by Mailtrap $port = '2525'; $smtp = Mail::factory('smtp', [ 'host' => $host, 'auth' => true, 'username' => $username, 'password' => $password, 'port' => $port ]); $mail = $smtp->send($to, $headers, $body); if (PEAR::isError($mail)) { echo('<p>' . $mail->getMessage() . '</p>'); } else { echo('<p>Message successfully sent!</p>'); }
Of course, we still used a fake SMTP in this email example to make sure we don’t flood real customers with our test emails as we try out different plugins.
Swift Mailer
Swift Mailer is one more widely used PHP external package for sending emails. The features you get with it are complex HTML template creation, adding attachments, inserting images, and sending emails through an authenticated SMTP server. And you can extend the package’s functionality with additional plugins, too.
Here’s an example of a booking confirmation email using Swift Mailer:
<?php require_once './vendor/autoload.php'; try { // Create the SMTP transport $transport = (new Swift_SmtpTransport('smtp.mailtrap.io', 2525)) ->setUsername('1a2b3c4d5e6f7g') ->setPassword('1a2b3c4d5e6f7g'); $mailer = new Swift_Mailer($transport); // Create a message $message = new Swift_Message(); $message->setSubject('Thanks for choosing Our Hotel!'); $message->setFrom(['[email protected]' => 'Your Hotel']); $message->addTo('[email protected]','Me'); // Add attachment $attachment = Swift_Attachment::fromPath('./confirmations/yourbooking.pdf'); $message->attach($attachment); // Set the plain-text part $message->setBody('Hi there, we are happy to confirm your booking. Please check the document in the attachment.'); // Set the HTML part $message->addPart('Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.', 'text/html'); // Send the message $result = $mailer->send($message); } catch (Exception $e) { echo $e->getMessage(); }
As you can see, there are different ways you can go with bulk email sending in PHP. While Pear Mail and Swift Mailer are suitable options for mass email sending in PHP, they are a bit complicated to get the hang of. Of course, there are tutorials and official documentation out there that you can check out, but we prefer PHPMailer for bulk emailing — it’s just simpler to get started with.
How to send test messages with PHPMailer?
Testing your email campaigns before sending them out to real users is crucial to make sure you don’t spam your customers or potential buyers, as well as it allows you to perfect your emails before they see the world. So how do you set up a test email in PHPMailer?
The answer is simple and has already been revealed in this article — use a fake SMTP server. You can prepare your test email as usual but don’t use a real SMTP to send it so that you can create a kind of test environment for your first emails.
So let’s review some examples. Most likely, you’ll be using HTML to create your email, so we’ll be looking at HTML messages.
A basic test HTML email
To get started, perform one of the following steps:
- if you’ve used Composer to install PHPMailer, include php file generated in Composer:
require 'path/to/composer/vendor/autoload.php';
- if you’ve installed PHPMailer manually, start with the following:
require path/to/PHPMailer/src/PHPMailer.php'; require path/to/PHPMailer/src/SMTP.php'; require path/to/PHPMailer/src/Exception.php';
- if you’ve used Composer to install PHPMailer, include php file generated in Composer:
Next, create a class for PHPMailer:
<?php use PHPMailer\PHPMailer\PHPMailer;
Then, create a new PHPMailer object:
$mail = new PHPMailer();
Now it’s time to configure a fake SMTP server:
$mail->isSMTP(); $mail->Host = '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;
Let’s work with the email recipients’ information now. Specify the headers, including multiple recipients as a new command each:
$mail->setFrom('[email protected]', 'Mailtrap'); $mail->addReplyTo('[email protected]', 'Mailtrap'); $mail->addAddress('[email protected]', 'Tim'); $mail->addCC('[email protected]', 'Elena'); $mail->addBCC('[email protected]', 'Alex'); $mail->AddBCC('[email protected]', 'Anna'); $mail->AddBCC('[email protected]', 'Mark');
Give your email a subject:
$mail->Subject = 'Test Email via Mailtrap SMTP using PHPMailer';
Now we’ve got to the email body. To create a test email in HTML, set the format of the email with the following property:
$mail->isHTML(true);
And now, you can include the contents of your basic test HTML email:
$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;
If you want to add media or make your HTML email more appealing with different formatting, you definitely can do it. If fact, PHPMailer allows the following:
- reading the body of an HTML email from an external file, like an HTML email template
- embedding referenced images
- converting HTML into plain text
- converting HTML into plain text
In such a way, you don’t have to write lots of code and update it every time you want to change something in your template — use the following attributes to link an external HTML file:
$mail->msgHTML(file_get_contents('contents.html'), __DIR__);
Lastly, input attributes to confirm email sending:
if($mail->send()){ echo 'Message has been sent'; }else{ echo 'Message could not be sent.'; echo 'Mailer Error: ' . $mail->ErrorInfo; }
That’s it, you can run your code now. If you get the “Message has been sent” message after you run your code — congrats, you’ve sent your first test email via PHPMailer!
The next step is to go to your Mailtrap inbox to see how your test email looks from the perspective of a recipient. You can also review your code for email sending, get analytics and check your sender reputation with Mailtrap.
If you’ve successfully sent your test email with PHPMailer, you can now switch to a real SMTP server of choice to reach your customers.
Adding attachments to your test HTML email
Here are the commands to use if you want to attach files in different ways:
- to attach a file, specify its path:
$mail->addAttachment('path/to/invoice1.pdf', 'invoice1.pdf');
(to add one more file, repeat the command)
- to add an attachment from the string, use the following:
$mysql_data = $mysql_row['blob_data']; $mail->addStringAttachment($mysql_data, 'db_data.db');
- to add a file via a link, use the same addStringAttachment() command:
$mail->addStringAttachment(file_get_contents($url), 'myfile.pdf');
- to embed an image, use a CID attachment:
$mail->addEmbeddedImage('path/to/image_file.jpg', 'image_cid'); $mail->isHTML(true); $mail->Body = '<img src="cid:image_cid">';
Having added as many files as you need, you can try sending out your test email. For example, you should have your HTML email with an inlined image look something like the following:
<?php use PHPMailer\PHPMailer\PHPMailer; require 'path/to/composer/vendor/autoload.php'; $mail->isSMTP(); $mail->Host = '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('[email protected]', 'First Last'); $mail->addReplyTo('[email protected]', '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';
Of course, if you get your “Message has been sent” notification, you can go to your Mailtrap inbox to see how the attachments look in your test email. And if there’s a problem, you can always go back and fix the email before it reaches a real customer since you’ve been using a fake SMTP server.
Debugging
As you set up PHPMailer and use it for your email sending, you may come across some bugs here and there. But you can easily handle the errors with the SMTPDebug command and find out what to fix and how to do that.
There are several debug levels to know when you’re using this command:
- debug level 1 — client, shows messages the client sent
- debug level 2 — client & server, this is the recommended level, shows messages the client and the server sent
- debug level 3 — client, server & connection, shows messages the client and the server sent + initial information
- debug level 4 — low-level information.
To start SMTP debugging, use the following script indicating the debug level:
$mail->SMTPDebug = 2;
If you can’t connect to the server at all, use debug level 3 or 4. If you need to turn off the debugging mode, such as for production, use debug level 0.
Here are a couple of debugging examples next.
- Invalid credentials
2018-12-12 14:49:26 Connection: opening to smtp.mailtrap.io:2525, timeout=300, options=array() 2018-12-12 14:49:26 Connection: opened 2018-12-12 14:49:26 SMTP INBOUND: "220 mailtrap.io ESMTP ready" 2018-12-12 14:49:26 SERVER -> CLIENT: 220 mailtrap.io ESMTP ready ... 2018-12-12 14:49:30 SMTP INBOUND: "535 5.7.0 Invalid login or password" 2018-12-12 14:49:30 SERVER -> CLIENT: 535 5.7.0 Invalid login or password 2018-12-12 14:49:30 SMTP ERROR: Username command failed: 535 5.7.0 Invalid login or password 2018-12-12 14:49:30 SMTP Error: Could not authenticate. 2018-12-12 14:49:30 CLIENT -> SERVER: QUIT 2018-12-12 14:49:30 SMTP INBOUND: "221 2.0.0 Bye" 2018-12-12 14:49:30 SERVER -> CLIENT: 221 2.0.0 Bye 2018-12-12 14:49:30 Connection: closed 2018-12-12 14:49:30 SMTP connect() failed. Mailer Error: SMTP connect() failed.
In this example, you can see that the login credentials, particularly the login and the password combination, are not found, while the rest of the input is correct. So you will then have to enter the right credentials to fix the error.
- Invalid SMTP hostname
2018-12-12 14:51:32 Connection: opening to mailtrap.io:2525, timeout=10, options=array() 2018-12-12 14:51:42 Connection failed. Error #2: stream_socket_client(): unable to connect to mailtrap.io:2525 (Operation timed out) [/Users/xxxx/Downloads/PHPMailer/src/SMTP.php line 326] 2018-12-12 14:51:42 SMTP ERROR: Failed to connect to server: Operation timed out (60) 2018-12-12 14:51:42 SMTP connect() failed. Mailer Error: SMTP connect() failed.
Because we’ve entered mailtrap.io instead of smtp.mailtrap.io, we receive the error message, and changing the hostname to the valid one will fix it.
What else you should know about PHPMailer
This guide on how to use PHPMailer to send emails in PHP explains how to install PHPMailer, configure a fake SMTP with Mailtrap for test email sending, send bulk emails via external mail packages, send HTML test messages with PHPMailer and debug errors.
But there is so much more you may need to learn about sending test emails in PHP via PHPMailer or the standard function, such as various encryption and user authentication methods.
Still, this guide is extensive enough to open the world of extensive email creation features and get you started with email sending in PHP.
Leave a Reply