PHPMailer: sending SMTP mail from PHP without a local mail server
The classic email sending library for PHP
At a glance
- What is it?
- PHPMailer is the long-standing PHP mail class that replaces mail() with an SMTP client, authentication and MIME handling. This review covers how it works, how to install it with Composer and send a first authenticated message, and where its design stops being the right choice.
- Who is it for?
- Adopt PHPMailer when you need to send mail from plain PHP without a local mail server, when you want SMTP authentication and attachments without building MIME by hand, or when you are maintaining an application that already depends on it.
- Can I use it commercially?
- Yes, with conditions. LGPL-2.1 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What PHPMailer replaces, and who actually needs it
The README is blunt about the problem: the only PHP function that sends mail directly is mail(), and it offers no help with authentication, HTML bodies or attachments. Formatting a message correctly means following overlapping standards for encoding and headers, and the README states that most code found online which calls mail() directly is wrong or unsafe. PHPMailer exists to absorb that work.
The audience is therefore PHP developers who need to send mail from application code and cannot rely on a local mail server. The README notes that Windows usually ships no local mail server, whereas Linux, BSD and macOS typically front mail() with sendmail. PHPMailer's integrated SMTP client removes that dependency: it talks to a remote SMTP host directly, on any platform. The README also points out that mail() should be avoided when possible and that SMTP to localhost is both faster and safer, citing a paper on mail() exploitation.
It is not only for greenfield code. The README lists WordPress, Drupal, 1CRM, SugarCRM, Yii and Joomla! among the projects using it, so a large share of adopters meet PHPMailer as a transitive dependency they must configure rather than as a library they chose.
How the SMTP client and MIME layer fit together
PHPMailer is a stateful sender object. You configure it, then call send(). The repository layout reflects a small set of classes: src/PHPMailer.php holds the message and sending logic, src/SMTP.php implements the SMTP transport, src/POP3.php covers POP-before-SMTP, and src/Exception.php is the error type. The README's minimal installation section says src/PHPMailer.php is required at minimum, src/SMTP.php is needed when using SMTP, and that the Exception class must be loaded even if you do not use exceptions, because it is used internally.
On the message side, the feature list covers multiple To, CC, BCC and Reply-to addresses, multipart/alternative output so clients that cannot read HTML still get a text part, attachments including inline ones, UTF-8 content, and 8bit, base64, binary and quoted-printable encodings. It also supports iCal events in multiparts and attachments, automatic address validation, header injection protection, DKIM and S/MIME signing, and error messages in more than 50 languages.
On the transport side, authentication supports LOGIN, PLAIN, CRAM-MD5 and XOAUTH2 over SMTPS and SMTP+STARTTLS. The README notes full UTF-8 support when the server supports SMTPUTF8, and the repository carries a separate SMTPUTF8.md document for that topic. The split between the sender class and the SMTP class is the architectural point: the same message-building code can go out through SMTP, through sendmail, or through mail(), which is why the examples directory contains separate smtp.phps, sendmail.phps and mail.phps files.
Installing PHPMailer with Composer and sending a first SMTP message
The README calls Composer the recommended installation path and gives the package name phpmailer/phpmailer, versioned with semantic versioning. Run this from your project root; Composer writes the vendor directory and the vendor/autoload.php script, which the README notes are generated by Composer and are not part of PHPMailer.
composer require phpmailer/phpmailerIf you manage composer.json by hand instead, the README gives this line to add:
"phpmailer/phpmailer": "^7.0.0"Composer is not the only route. The README states you can download PHPMailer as a zip file, with the caveat that docs and examples are not included in that zip, copy the PHPMailer folder into an include_path directory from your PHP configuration, and load the class files manually. That path needs explicit requires, and the README warns that Exception.php is required even when you do not use exceptions:
<?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';With the library loaded, the shape of a first send is the same in both cases: create a PHPMailer instance, point it at an SMTP host, enable SMTP authentication, supply credentials, then set the addresses and body and call send(). The repository ships runnable versions of these flows as .phps files in examples/, including examples/smtp.phps for plain SMTP, examples/gmail.phps for Gmail, examples/gmail_xoauth.phps for Gmail over XOAUTH2, examples/smtp_check.phps for testing a connection, examples/send_file_upload.phps for attachments, and examples/mailing_list.phps for looped sending. Open the one matching your provider rather than assembling configuration from scratch.
For Gmail and other providers that require OAuth instead of a password, the README states you must additionally depend on league/oauth2-client plus the appropriate service adapter, and it points to the SendOauth2 wrapper by decomplexity for Microsoft services. The repository also includes get_oauth_token.php and examples/sendoauth2.phps, so the OAuth route has first-party examples even though the OAuth client itself is a separate dependency.
Where PHPMailer is the wrong tool
The README itself says not to roll your own and lists Symfony Mailer, Laminas/Mail and ZetaComponents as alternatives to look at. That is an unusually candid framing for a project page, and it maps to a real boundary: if your application is already built on Symfony or Laminas, you have a mailer with its own transport configuration, and adding PHPMailer means maintaining two mail paths and two sets of credentials.
The second boundary is architectural. PHPMailer is a mutable sender object, not an immutable message value. Each message is built by calling setters on an instance, and sending is a side effect on that instance. If your code wants to construct a message as data, serialize it, queue it, and hand it to a transport later, you are working against the grain of the API. The examples directory shows the intended style: a script that configures one instance and sends.
Third, the README is explicit that PHPMailer 5.2 is no longer supported, even for security updates, and that its last release lives on the 5.2-stable branch. If you inherit a codebase pinned to 5.2, you are running an unmaintained mail library, and the upgrade path is documented in UPGRADING.md rather than in the README. The README also notes that the 5.2 source files sat outside src/ and that the namespace PHPMailer\PHPMailer was introduced later, which is why the upgrade is not a version bump alone.
Symfony Mailer and Laminas/Mail as the real alternatives
The README names Symfony Mailer, Laminas/Mail and ZetaComponents/Mail as libraries to consider before writing your own sender. The meaningful difference is not feature coverage, since all three send mail, but where the message object lives.
Symfony Mailer is the mail component of the Symfony framework. Its documentation describes a mailer built around an Email object and a Transport abstraction, which is the opposite arrangement from PHPMailer's stateful sender: you construct a message, then hand it to a transport. If you are inside a Symfony application, that object is already wired into the container, and the transport configuration lives in framework configuration rather than in a PHP script. The cost of choosing PHPMailer there is that you configure SMTP twice and your team has two mental models for the same task.
Laminas/Mail follows the same component philosophy for the Laminas and Mezzio ecosystem, and ZetaComponents/Mail is a further option in the same family. The practical test is simple: if your framework already ships a mailer, use it. PHPMailer's advantage appears when there is no framework mailer to use, when you are in legacy code that predates one, or when you specifically want its SMTP client and its examples for providers such as Gmail. Its XOAUTH2 support is also a concrete reason to pick it, though the README makes clear that the OAuth client itself is a separate dependency you must add.
Maintenance cadence, the 5.2 dead end, and the LGPL 2.1 question
The repository is not archived, and the last push was on 2026-09-10, so the project is being worked on. The recent release history shows v7.1.1 on 2026-05-18, v7.1.0 on 2026-05-15 and v7.0.2 on 2026-01-09. The versioning is semantic, and the README's recommended constraint is ^7.0.0, which means patch and minor releases arrive without a code change on your side. The upgrade cost between 7.x minors should therefore be low, but the 5.2 to 7.x jump is a different matter: UPGRADING.md exists precisely because the source layout and namespace changed, and the README states that 5.2 receives no security updates at all.
Licensing is where PHPMailer differs from many PHP libraries. It is distributed under LGPL 2.1, together with the GPL Cooperation Commitment, and the README directs readers to the LICENSE file for availability and distribution terms. LGPL is not the permissive MIT or BSD licence that most Composer packages use: it carries obligations around relinking and around distributing modified versions of the library itself. For a typical application that requires the package and links against it unmodified, this is usually unremarkable, but if you fork PHPMailer, ship a modified copy, or bundle it into a product whose licensing you have already settled, the terms deserve a reading rather than an assumption. This is not legal advice, and the LICENSE file is the authoritative text.
Two operational notes from the README are worth carrying into a maintenance plan. The library validates addresses and protects against header injection, so some classes of malformed input are handled inside the library rather than by your code. And error messages are available in over 50 languages, which matters if you surface send failures to end users rather than only to logs.
Editorial conclusion
Adopt PHPMailer when you need to send mail from plain PHP without a local mail server, when you want SMTP authentication and attachments without building MIME by hand, or when you are maintaining an application that already depends on it. Do not adopt it as a framework mail abstraction: if you are on Symfony, Laravel or Zend Framework, the mailer already in that stack is the better fit, and if you want an object model for messages rather than a stateful sender, PHPMailer will feel procedural. Before committing, verify three things: that your PHP version is covered (the README states PHP 5.5 and later, including PHP 8.5), that you have a plan for the LGPL 2.1 obligations in your distribution, and that your SMTP credentials or XOAUTH2 setup actually authenticate against your provider, because the library will not guess that for you.
Frequently asked questions
What is PHPMailer used for?
It sends email from PHP code, replacing the built-in mail() function with an integrated SMTP client, authentication, HTML and multipart messages, and attachments. The README lists WordPress, Drupal, 1CRM, SugarCRM, Yii and Joomla! among the projects that use it.
How do I install PHPMailer?
The README recommends Composer and gives the command composer require phpmailer/phpmailer, or the line "phpmailer/phpmailer": "^7.0.0" in composer.json. Without Composer you can download the zip, copy the PHPMailer folder into an include_path directory, and require the class files manually, including Exception.php.
How do I install PHPMailer using Composer?
Run composer require phpmailer/phpmailer from your project root. Composer generates the vendor folder and vendor/autoload.php, which the README notes are not part of PHPMailer itself.
How do I use PHPMailer with Gmail?
The repository ships examples/gmail.phps for Gmail and examples/gmail_xoauth.phps for Gmail over XOAUTH2. For XOAUTH2 the README states you must also add a dependency on league/oauth2-client and the appropriate service adapter.
Can I use PHPMailer without Composer?
Yes. The README describes downloading PHPMailer as a zip file, noting that docs and examples are not included in that zip, then copying the PHPMailer folder into an include_path directory and loading each class file manually. Exception.php must be loaded even if you do not use exceptions.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/phpmailer-phpmailer)
Community notes