Join us
@nataliiapolomkina ă» Sep 26,2022 ă» 12 min read ă» 2637 views ă» Originally posted on mailtrap.io
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!Â
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 a list of advanced features:
To send emails with PHPMailer and SMTP, you need to install PHPMailer and configure SMTP settings first.
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 release 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 the 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 is a separate section of this post.
To see detailed instructions on installation, check PHPMailer documentation on Github.
To test PHP mail functionality, we will use Mailtrap, a fake SMTP server, so as not to flood our inboxes or even worse, the inboxes of our customers. Once you make sure that everything works properly and your email messages look right, you will be able to easily substitute the SMTP settings in our examples with your real serverâs.
If you are not using Mailtrap yet, create a free account , go to your Inbox, and copy the following values from the SMTP settings tab 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
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.
Most likely, you will use HTML to design your email notification. So, letâs review some examples of using HTML methods and attributes.
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 = '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 executes correctly. To check the delivery result and details, go to your Mailtrap inbox: your messages will get there in seconds.Â
With Mailtrap, you will be able to review your HTML code, raw data, perform email browser testing as well as make sure your message wonât be marked as spam, or your sending domain wonât go blacklisted.
There are two options for adding files to your message:Â
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 = '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.
With Mailtrap, you will be able to review your HTML code, raw data, perform email browser testing as well as make sure your message wonât be marked as spam, or your sending domain wonât go blacklisted. Â
Once you have verified that your PHPMailer sending result matches your expectations, you can switch to regular email sending via any preferred SMTP server.
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 = '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();
Gmail is one of the most popular SMTP servers, which allows you to send emails for free. However, it does require some tinkering with authentication settings.
Here are the basic Gmail SMTP credentials:$mail->SMTPSecure = 'tls';
$mail->Host = 'smtp.gmail.com';
$mail->Port = 587;
or
$mail->SMTPSecure = 'ssl';
$mail->Host = 'smtp.gmail.com';
$mail->Port = 465;
If you donât use the 2-step verification for your account, use your Gmail address and password to your Gmail account.Â
You should Allow less secure apps in your account settings. Please note that it may take an hour or two for this setting to come into effect. In some cases, you might additionally need to make necessary changes on the unlock CAPTCHA page.Â
If something goes wrong, you will receive an error â5.7.14 Please log in via your web browser and then try againâ or âUsername and Password not acceptedâ. It should contain instructions on how to fix it.
If 2-step verification is enabled for your Gmail account and you wish to use it with PHPMailer as well, you will need to create an App password to continue. It is a 16-digit passcode, which you should put as a value to $mail->Password. It is easy to generate one following these Google instructions.Â
OAuth2 is the most complicated but still the recommended method. Fortunately, there is oauth2-google. It is a package to support Google OAuth 2.0 for the PHP Leagueâs OAuth 2.0 Client. It supports PHP 7.0 â PHP 7.3. To use it, you need to get a Google client ID and client secret first. Follow this Googleâs guide to set everything up. Once completed, install the package with composer and add the authorization details as below:
composer require league/oauth2-google
use League\OAuth2\Client\Provider\Google;
$provider = new Google([
'clientId' => '{google-client-id}',
'clientSecret' => '{google-client-secret}',
'redirectUri' => 'https://example.com/callback-url',
]);
For more details, follow the oauth2-google on GitHub.Â
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();
If you experience some troubles when sending emails through an SMTP server, the SMTPDebug command will help you explore those errors and find out what should be fixed.Â
Enable SMTP debugging and set the debug level in your script as follows:
$mail->SMTPDebug = 2;
Use level 3 or level 4 if you are not able to connect at all. Setting level 0 will turn the debugging off, it is usually used for production.Â
For a better understanding of how debugging in PHPMailer works, letâs review a couple of examples.Â
Example1. 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.
For this example, we entered an invalid hostname: mailtrap.io instead of smtp.mailtrap.io. and instantly received a message that an error has occurred at the very first stage of communication with the server.Â
Example 2. 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.
This example demonstrates where the error occurs: now the SMTP, its hostname, and port are valid but a combination of login and password was not found, so you should double-check and modify your credentials.
There are a couple of detailed articles on GitHub about debugging and troubleshooting, refer to them when you need to dive deeper into these topics.Â
In this tutorial we have reviewed the most common PHPMailer use cases: creating HTML emails with images and attachments, sending them via SMTP or localhost to different types of recipients along with debugging options.Â
If you need more specific examples, check the âexamplesâ folder inside PHPMailer documentation on Github.Â
Thanks for reading our guide on how to send bulk emails with attachments using PHPMailer. The article was initially published in the Mailtrap blog by Dmitriy Shcherbakan.
Join other developers and claim your FAUN account now!
Influence
Total Hits
Posts
Only registered users can post comments. Please, login or signup.