If you need to send email in PHP, PHPMailer remains a practical SMTP client for application workflows like signup verification, password resets, and transactional notifications.

This guide focuses on a production-safe setup instead of quick scripts that fail under real traffic.

Why PHPMailer instead of raw mail()

mail() can work for basic scenarios, but PHPMailer gives you better SMTP control, authentication handling, structured MIME support, and safer error reporting.

Use PHPMailer when you need:

  • authenticated SMTP delivery
  • HTML and plain-text multipart messages
  • attachment handling
  • better diagnostics for failed sends

1) Install PHPMailer with Composer

composer require phpmailer/phpmailer

Then load the autoloader:

<?php
require __DIR__ . '/vendor/autoload.php';

2) Configure SMTP securely with environment variables

Do not hardcode credentials in source.

<?php

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

require __DIR__ . '/vendor/autoload.php';

$mail = new PHPMailer(true);

try {
    $mail->isSMTP();
    $mail->Host = getenv('SMTP_HOST');
    $mail->SMTPAuth = true;
    $mail->Username = getenv('SMTP_USER');
    $mail->Password = getenv('SMTP_PASS');
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port = (int) getenv('SMTP_PORT');

    $mail->setFrom('no-reply@example.com', 'Example App');
    $mail->addAddress('user@example.com');
    $mail->addReplyTo('support@example.com', 'Support Team');

    $mail->Subject = 'Welcome to Example App';
    $mail->isHTML(true);
    $mail->Body = '<h1>Welcome</h1><p>Your account is ready.</p>';
    $mail->AltBody = 'Welcome. Your account is ready.';

    $mail->send();
    echo 'Message sent';
} catch (Exception $e) {
    error_log('PHPMailer error: ' . $mail->ErrorInfo);
}

3) Attachments and multipart content

PHPMailer supports both body formats and attachments in one message:

$mail->isHTML(true);
$mail->Body = '<p>Invoice attached.</p>';
$mail->AltBody = 'Invoice attached.';
$mail->addAttachment(__DIR__ . '/invoices/invoice-123.pdf', 'invoice.pdf');

Keep attachment size aligned with your provider limits and deliverability policy.

If recipients are user-submitted, validate them before PHPMailer sends. Start with PHP email validation for syntax and DNS checks, then use the Email Validation API when signup quality or lifecycle data matters.

4) SMTP settings checklist

Before production, confirm:

  1. Host, port, TLS mode, and auth type match provider requirements.
  2. Sending domain has SPF, DKIM, and DMARC configured.
  3. Bounce and complaint handling exists in your pipeline.
  4. Rate limits and retry behavior are defined for high-volume sends.

Related guidance: SMTP authentication and SMTP relay.

Common PHPMailer errors and fixes

Error patternLikely causeFix
535 Authentication failedWrong credentials or auth policy mismatchVerify credentials, app passwords, and SMTP auth policy
Could not connect to SMTP hostPort/TLS mismatch or network egress blockCheck 587 vs 465, TLS mode, firewall rules
Timeouts or deferred sendsRecipient throttling or provider back-pressureAdd queue/retry strategy and rate controls
Messages delivered to spamMissing auth alignment or weak content qualityValidate SPF/DKIM/DMARC and run spam/deliverability checks

Test PHPMailer flows before release

Do not validate only "send success". Validate full send-and-receive behavior:

PHPMailer vs API-based sending

PHPMailer is great when your architecture is SMTP-centric. API-based sending can simplify retries, observability, and provider-side controls.

If you need both programmatic inbox and send workflows in one stack, review Email API capabilities.

Final take

PHPMailer is still a strong choice for PHP email delivery when configured with proper SMTP security and tested end-to-end.

Use environment-managed secrets, explicit TLS/auth settings, and release-gate testing so email failures are caught before users see them.