PHPMailer is the most widely used library for sending email from PHP. It wraps SMTP so you configure a host, port, and credentials once, then build and send messages with a clear object API. PHP's built-in `mail()` function does too little (no authentication, weak error reporting), which is why most projects reach for PHPMailer instead. Here is a complete, working send.

## How do you install PHPMailer?

Use Composer:

```bash
composer require phpmailer/phpmailer
```

Then load the autoloader and import the classes you need:

```php
<?php
require "vendor/autoload.php";

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
```

## How do you configure SMTP and send a message?

Create a `PHPMailer` instance, switch it into SMTP mode with `isSMTP()`, then set the connection and message fields. Wrap the call in try/catch so a failed send is reported rather than swallowed:

```php
<?php
$mail = new PHPMailer(true); // true enables exceptions

try {
    // Server settings
    $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;

    // Recipients
    $mail->setFrom("you@yourdomain.com", "Your App");
    $mail->addAddress("recipient@example.org", "Recipient Name");

    // Content
    $mail->isHTML(true);
    $mail->Subject = "Your receipt";
    $mail->Body    = "<p>Thanks for your order.</p>";
    $mail->AltBody = "Thanks for your order. This is the plain-text version.";

    $mail->send();
    echo "Message sent.";
} catch (Exception $e) {
    echo "Send failed: {$mail->ErrorInfo}";
}
```

A few details that trip people up. `SMTPSecure` and `Port` go together: use `ENCRYPTION_STARTTLS` with 587, or `ENCRYPTION_SMTPS` with 465. `isHTML(true)` tells PHPMailer the `Body` is HTML and to send `AltBody` as the plain-text alternative. Pass `true` to the constructor so failures throw an `Exception` instead of returning `false` silently.

## How do you add an attachment?

Call `addAttachment` with a file path before `send()`:

```php
<?php
$mail->addAttachment("./invoices/invoice-1042.pdf", "invoice.pdf");
```

The second argument renames the file as the recipient sees it. You can call it more than once for multiple attachments.

## Send it with Bird

PHPMailer talks SMTP, which means production needs a mail server with a clean reputation, correct authentication records, and somewhere to see what happened after sending. An HTTP API removes the server. You send JSON over HTTPS and get a structured response. With the [Bird email API](/products/email) the same message is one call:

```php
use Bird\Bird;

$bird = new Bird(getenv("BIRD_API_KEY"));

$bird->emails->send([
  "from"    => "you@yourdomain.com",
  "to"      => "delivered@bird.dev",
  "subject" => "Hello from PHP",
  "html"    => "<p>It works.</p>",
]);
```

The `delivered@bird.dev` sandbox address always accepts mail, so you can verify the integration before sending to real inboxes. No SMTP socket, no port choice, no reputation to warm yourself.

## FAQ

### Why not just use PHP's mail() function?

`mail()` hands the message to the local sendmail binary with no SMTP authentication and almost no error reporting. PHPMailer authenticates against a remote server, supports TLS, builds multipart messages, and tells you why a send failed.

### What is the difference between Body and AltBody?

`Body` is the HTML version and `AltBody` is the plain-text fallback. With `isHTML(true)` set, clients that cannot render HTML show `AltBody`, which also helps with [deliverability](/products/email/deliverability).

### STARTTLS or SMTPS?

`ENCRYPTION_STARTTLS` on port 587 upgrades a plain connection to TLS, while `ENCRYPTION_SMTPS` on port 465 is encrypted from the start. Match the setting to the port your mail server expects.

PHPMailer is the right tool when you want to send over SMTP from PHP. When you would rather skip operating the server, the [sending email guide](/docs/guides/email/sending-email) shows the API path in full.