How to send emails using PHPMailer

PHPMailer is an open-source PHP library that provides a simple and convenient way to send emails. It supports several mail-transfer protocols and provides the easiest way to include attachments in the email. PHPMailer sends transactional, marketing, notification, and other types of emails.

How to install PHPMailer

To install the PHPMailer, we need to download it from its GitHub repositoryhttps://github.com/PHPMailer/PHPMailer. We require the files from the src folder. We can download it as a zip file and extract it in our project directory.

We could also download the PHPMailer with git by running the following command:

git clone https://github.com/PHPMailer/PHPMailer.git
Installing PHPMailer using git

A more convenient way to install PHPMailer is to download it using a package manager like Composer, which is a dependency manager for PHP. We can install it with Composer by running the following command in the terminal:

composer require phpmailer/phpmailer
Installing PHPMailer with composer

What is SMTP?

There are several mail transfer protocols for sending emails, such as SMTP. SMTP, short for Simple Mail Transfer Protocol, is an industry-standard email protocol. It relays emails from the sender’s server to the recipient’s server. It enhances security by enforcing authentication so only authorized users can send emails.

Sending emails using PHPMailer via SMTP protocol

Let’s see how we can send an email using PHPMailer via SMTP protocol. We’ll divide it into the following steps:

  1. Instantiate the PHPMailer instance.

  2. Authenticate with SMTP.

  3. Set the email sender, receiver, subject, and body.

  4. Add an attachment and send the email.

1. Instantiate the PHPMailer instance

<?php
namespace PHPMailer\PHPMailer;
require("PHPMailer/src/PHPMailer.php");
require("PHPMailer/src/SMTP.php");
$phpMailerInstance = new PHPMailer;

2. Configure and authenticate with SMTP

<?php
$phpMailerInstance->isSMTP();
$phpMailerInstance->SMTPAuth = true;
$phpMailerInstance->Username = 'email-using-phpmailer';
$phpMailerInstance->Password = 'mdMRQdWJ286CYJJh';
$phpMailerInstance->Host = 'mail.smtp2go.com';
$phpMailerInstance->Port = 2525;

3. Set the email sender, receiver, subject, and body

<?php
$phpMailerInstance->setFrom('email-using-phpmailer@kag.one', 'Email using PHPMailer');
$phpMailerInstance->addAddress('your-email-address@domain.com', 'Your name');
$phpMailerInstance->isHTML(true);
$phpMailerInstance->Subject = 'Demo for sending email with PHPMailer';
$phpMailerInstance->Body = 'This message contains HTML <strong>tags</strong>';
$phpMailerInstance->AltBody = 'This message contains plain text';

4. Add an attachment and send the email

<?php
$phpMailerInstance->addAttachment('attachment.txt');
if($phpMailerInstance->send()) {
echo 'E-mail has been sent';
} else {
echo 'Mailer Error: ' . $mail->ErrorInfo;
}

Let’s combine all the code together and see it in action.

<?php

/**
 * PHPMailer - PHP email creation and transport class.
 * PHP Version 5.5.
 *
 * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
 *
 * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
 * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
 * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
 * @author    Brent R. Matzelle (original founder)
 * @copyright 2012 - 2023 Marcus Bointon
 * @copyright 2010 - 2012 Jim Jagielski
 * @copyright 2004 - 2009 Andy Prevost
 * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
 * @note      This program is distributed in the hope that it will be useful - WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 */

namespace PHPMailer\PHPMailer;

/**
 * Configure PHPMailer with DSN string.
 *
 * @see https://en.wikipedia.org/wiki/Data_source_name
 *
 * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
 */
class DSNConfigurator
{
    /**
     * Create new PHPMailer instance configured by DSN.
     *
     * @param string $dsn        DSN
     * @param bool   $exceptions Should we throw external exceptions?
     *
     * @return PHPMailer
     */
    public static function mailer($dsn, $exceptions = null)
    {
        static $configurator = null;

        if (null === $configurator) {
            $configurator = new DSNConfigurator();
        }

        return $configurator->configure(new PHPMailer($exceptions), $dsn);
    }

    /**
     * Configure PHPMailer instance with DSN string.
     *
     * @param PHPMailer $mailer PHPMailer instance
     * @param string    $dsn    DSN
     *
     * @return PHPMailer
     */
    public function configure(PHPMailer $mailer, $dsn)
    {
        $config = $this->parseDSN($dsn);

        $this->applyConfig($mailer, $config);

        return $mailer;
    }

    /**
     * Parse DSN string.
     *
     * @param string $dsn DSN
     *
     * @throws Exception If DSN is malformed
     *
     * @return array Configuration
     */
    private function parseDSN($dsn)
    {
        $config = $this->parseUrl($dsn);

        if (false === $config || !isset($config['scheme']) || !isset($config['host'])) {
            throw new Exception('Malformed DSN');
        }

        if (isset($config['query'])) {
            parse_str($config['query'], $config['query']);
        }

        return $config;
    }

    /**
     * Apply configuration to mailer.
     *
     * @param PHPMailer $mailer PHPMailer instance
     * @param array     $config Configuration
     *
     * @throws Exception If scheme is invalid
     */
    private function applyConfig(PHPMailer $mailer, $config)
    {
        switch ($config['scheme']) {
            case 'mail':
                $mailer->isMail();
                break;
            case 'sendmail':
                $mailer->isSendmail();
                break;
            case 'qmail':
                $mailer->isQmail();
                break;
            case 'smtp':
            case 'smtps':
                $mailer->isSMTP();
                $this->configureSMTP($mailer, $config);
                break;
            default:
                throw new Exception(
                    sprintf(
                        'Invalid scheme: "%s". Allowed values: "mail", "sendmail", "qmail", "smtp", "smtps".',
                        $config['scheme']
                    )
                );
        }

        if (isset($config['query'])) {
            $this->configureOptions($mailer, $config['query']);
        }
    }

    /**
     * Configure SMTP.
     *
     * @param PHPMailer $mailer PHPMailer instance
     * @param array     $config Configuration
     */
    private function configureSMTP($mailer, $config)
    {
        $isSMTPS = 'smtps' === $config['scheme'];

        if ($isSMTPS) {
            $mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        }

        $mailer->Host = $config['host'];

        if (isset($config['port'])) {
            $mailer->Port = $config['port'];
        } elseif ($isSMTPS) {
            $mailer->Port = SMTP::DEFAULT_SECURE_PORT;
        }

        $mailer->SMTPAuth = isset($config['user']) || isset($config['pass']);

        if (isset($config['user'])) {
            $mailer->Username = $config['user'];
        }

        if (isset($config['pass'])) {
            $mailer->Password = $config['pass'];
        }
    }

    /**
     * Configure options.
     *
     * @param PHPMailer $mailer  PHPMailer instance
     * @param array     $options Options
     *
     * @throws Exception If option is unknown
     */
    private function configureOptions(PHPMailer $mailer, $options)
    {
        $allowedOptions = get_object_vars($mailer);

        unset($allowedOptions['Mailer']);
        unset($allowedOptions['SMTPAuth']);
        unset($allowedOptions['Username']);
        unset($allowedOptions['Password']);
        unset($allowedOptions['Hostname']);
        unset($allowedOptions['Port']);
        unset($allowedOptions['ErrorInfo']);

        $allowedOptions = \array_keys($allowedOptions);

        foreach ($options as $key => $value) {
            if (!in_array($key, $allowedOptions)) {
                throw new Exception(
                    sprintf(
                        'Unknown option: "%s". Allowed values: "%s"',
                        $key,
                        implode('", "', $allowedOptions)
                    )
                );
            }

            switch ($key) {
                case 'AllowEmpty':
                case 'SMTPAutoTLS':
                case 'SMTPKeepAlive':
                case 'SingleTo':
                case 'UseSendmailOptions':
                case 'do_verp':
                case 'DKIM_copyHeaderFields':
                    $mailer->$key = (bool) $value;
                    break;
                case 'Priority':
                case 'SMTPDebug':
                case 'WordWrap':
                    $mailer->$key = (int) $value;
                    break;
                default:
                    $mailer->$key = $value;
                    break;
            }
        }
    }

    /**
     * Parse a URL.
     * Wrapper for the built-in parse_url function to work around a bug in PHP 5.5.
     *
     * @param string $url URL
     *
     * @return array|false
     */
    protected function parseUrl($url)
    {
        if (\PHP_VERSION_ID >= 50600 || false === strpos($url, '?')) {
            return parse_url($url);
        }

        $chunks = explode('?', $url);
        if (is_array($chunks)) {
            $result = parse_url($chunks[0]);
            if (is_array($result)) {
                $result['query'] = $chunks[1];
            }
            return $result;
        }

        return false;
    }
}
Send email in PHP using PHPMailer via SMTP

On line 13, change the receiver’s email address and name to your email address and name. An email will arrive in your inbox when you click on the “Run” button.

Code explanation

Lines 2–5: We add the namespace required files, and create an instance of the PHPMailer class.

Lines 6–11: We set username and password for authentication, and configure SMTP host and port.

Lines 12–17: We instruct the PHPMailer to send email as HTML, and set the email sender, receiver, subject, and body.

Lines 18–25: We add an attachment and send the email.

We can add multiple attachments by calling the addAttachment method multiple times.

Advanced features of PHPMailer

Other than the basic features, PHPMailer provides some advanced features, including but not limited to the following:

Custom headers: PHPMailer provides a custom method addCustomHeader() to add the functionality to include the additional meta data to control all the aspects of email delivery.

Embedded images: We can embed images in the email by using the addEmbeddedImage() method.

SMTPKeepAlive property: PHPMailer provides the functionality to keep the SMTP connection alive. By keeping the SMTP connection alive, we can achieve low latency, which results in better performance. We can do this by setting the SMTPKeepAlive property of the PHPMailer instance to true.

Conclusion

PHPMailer provides a convenient way to send emails, including attachments, by providing simple methods to configure the email. We often need to send transactional or notification emails to our application’s users while working on a real-world project, and PHPMailer provides an easy way to perform SMTP authentication and send all kinds of emails.

Copyright ©2024 Educative, Inc. All rights reserved