Installing PHPMailer (Composer and Manual)

0

How to install PHPMailer 6.x — with Composer, or by hand when Composer is not available — plus the PHP extensions it needs and how to confirm the installation works before you write any application code.

Requirements

Requirement Needed for
PHP 5.5+ The library itself. Current PHP versions are fully supported.
ext-openssl Any TLS connection — so any real SMTP server.
ext-mbstring Correct encoding of non-ASCII subjects and bodies.
ext-filter Address validation. Enabled by default in practice.
ext-hash DKIM signing.

Check what you have before installing:

php -m | grep -E 'openssl|mbstring|filter|hash'
php -r 'echo PHP_VERSION, PHP_EOL;'

Missing openssl is the one that will stop you dead: every hosted SMTP provider requires TLS, so without it you cannot authenticate anywhere.

Install with Composer

composer require phpmailer/phpmailer

That is the whole installation. Composer resolves the version, downloads it into vendor/, and registers the autoloader. In your code:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

Three namespaced classes, three purposes: PHPMailer is the mailer and holds the encryption and charset constants, SMTP holds the debug constants, and Exception is PHPMailer’s own exception type. Import that last one — catching the global \Exception works but will also swallow unrelated failures.

Pinning the version

composer require phpmailer/phpmailer:^6.9

Worth doing in a project you will not revisit for a while. ^6.9 accepts patch and minor updates within the 6.x line but never crosses to a new major version, so a future release cannot break your code without an explicit action from you.

Production install

composer install --no-dev --optimize-autoloader

Skips test dependencies and builds a classmap, which is measurably faster on every request.

Install without Composer

Perfectly workable — you just have to load the class files and register the namespace yourself. Download a release from the releases page and copy the src/ directory into your project.

Three files matter:

File Required
src/PHPMailer.php Always.
src/SMTP.php For SMTP sending.
src/Exception.php When exceptions are enabled — which they should be.
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
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';

$mail = new PHPMailer(true);

The order matters: Exception.php before PHPMailer.php. The use statements are still needed — they are namespace imports, independent of how the files got loaded.

SMTP.php is only optional if you are using the mail() or sendmail transports. Requiring it always costs nothing.

Optional autoloader

For more than a couple of entry points, register a small PSR-4 loader instead of three require lines everywhere:

spl_autoload_register(function ($class) {
    $prefix = 'PHPMailer\\PHPMailer\\';
    if (strpos($class, $prefix) !== 0) {
        return;
    }
    $file = '/path/to/PHPMailer/src/' . substr($class, strlen($prefix)) . '.php';
    if (is_readable($file)) {
        require $file;
    }
});

Confirm it works

Test the installation on its own, before mixing it into application code. Two lines are enough to prove the classes load:

<?php
require 'vendor/autoload.php';
echo (new PHPMailer\PHPMailer\PHPMailer())->Version, PHP_EOL;

If that prints a version number, the library is installed correctly and any later problem is configuration, not installation.

Then test an actual send with debugging on, so a failure tells you why:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);
$mail->SMTPDebug = SMTP::DEBUG_SERVER;

try {
    $mail->isSMTP();
    $mail->Host       = 'smtp.example.com';
    $mail->SMTPAuth   = true;
    $mail->Username   = getenv('SMTP_USER');
    $mail->Password   = getenv('SMTP_PASS');
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port       = 587;

    $mail->setFrom('from@example.com', 'Install test');
    $mail->addAddress('you@example.com');
    $mail->Subject = 'PHPMailer install test';
    $mail->Body    = 'If you are reading this, the installation works.';

    $mail->send();
    echo "Sent.\n";
} catch (Exception $e) {
    echo 'Failed: ' . $mail->ErrorInfo, PHP_EOL;
}

Run it from the command line rather than the browser — you get the debug output unmangled, and no risk of leaving it exposed on a public URL.

Installation problems

Class “PHPMailer\PHPMailer\PHPMailer” not found

The autoloader was not loaded, or the path is wrong. With Composer, check that require 'vendor/autoload.php' resolves — use an absolute path (__DIR__ . '/vendor/autoload.php') if the script can be invoked from different working directories. Without Composer, check the three require paths and that Exception.php comes first.

Class “PHPMailer” not found

Code written for PHPMailer 5.x, which had no namespace. In 6.x the class is PHPMailer\PHPMailer\PHPMailer. Either add the use statement or reference it fully qualified. The old class.phpmailer.php file no longer exists.

Composer says your PHP version is too low

Composer resolves against the PHP version on the command line, which is often different from the one serving your site. Check both:

php -v
composer config platform.php   # what Composer is targeting

SSL routines / certificate verify failed on the first send

Not an installation problem — the CA bundle on the server is missing or stale. Point openssl.cafile at a current one in php.ini. Do not disable certificate verification to make it go away.

Upgrading from 5.x

5.x 6.x
require 'class.phpmailer.php'; require 'vendor/autoload.php';
new PHPMailer() new PHPMailer\PHPMailer\PHPMailer(true)
$mail->SMTPSecure = 'tls'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPDebug = 2; $mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->AddAddress() $mail->addAddress() — methods are camelCase

The string values still work, so 'tls' is not broken. The constants are simply harder to typo. PHPMailer 5.x has been end-of-life for years and receives no security fixes — treat an upgrade as maintenance, not an option.

Next

  • Tutorial — from installation to a working authenticated send.
  • SMTP Example — full SMTP configuration and every error it can produce.
  • Examples — one complete script per transport.
  • Properties Reference — everything configurable, with defaults.

sunshyne works on technical SEO and email deliverability for French-speaking markets, and runs the digital consultancy at sunshyne.ch. Most of that work sits where the two overlap. On the SEO side: redirect mapping, crawl and indexation diagnostics, server log analysis, and recovering domains whose history has damaged them. On the email side: the authentication layer — SPF, DKIM and DMARC — sender reputation, and the reasons a technically valid message still gets filtered. These PHPMailer pages exist because the second half of that work keeps returning to the same questions: which transport to use, why an SMTP connection fails, and why a correctly formed message is rejected anyway. The examples here are the ones worth keeping after answering those questions more than once.

Comments are closed.