Send Email with PHP: HTML, Text, and Attachments

Last updated: August 25, 2026.

For application email, send through an authenticated SMTP service and let a mail library construct the headers, HTML alternative, and attachments. The example below uses PHPMailer.

Install PHPMailer

composer require phpmailer/phpmailer

Composer installs PHPMailer and creates the autoloader used by the PHP example.

Send HTML and plain-text versions with an attachment

<?php
use PHPMailer\PHPMailer\PHPMailer;

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

$smtpHost = getenv('SMTP_HOST');
$smtpUsername = getenv('SMTP_USERNAME');
$smtpPassword = getenv('SMTP_PASSWORD');

if (!$smtpHost || !$smtpUsername || !$smtpPassword) {
    throw new RuntimeException('SMTP configuration is incomplete.');
}

$mail = new PHPMailer(true);

try {
    $mail->isSMTP();
    $mail->Host = $smtpHost;
    $mail->SMTPAuth = true;
    $mail->Username = $smtpUsername;
    $mail->Password = $smtpPassword;
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port = (int) (getenv('SMTP_PORT') ?: 587);

    $mail->setFrom('[email protected]', 'Example App');
    $mail->addAddress('[email protected]', 'Customer');

    $mail->isHTML(true);
    $mail->Subject = 'Your monthly report';
    $mail->Body = '<h1>Your report is ready</h1><p>See the attached PDF.</p>';
    $mail->AltBody = 'Your report is ready. See the attached PDF.';

    $attachment = __DIR__ . '/reports/monthly-report.pdf';
    if (!is_readable($attachment)) {
        throw new RuntimeException('Attachment is not readable.');
    }

    $mail->addAttachment($attachment, 'monthly-report.pdf');
    $mail->send();
} catch (Throwable $exception) {
    error_log('Email delivery failed: ' . $exception->getMessage());
}

Store SMTP credentials in environment variables or a secret manager. The From address should be authorized by the SMTP provider and aligned with the domain’s email authentication settings.

Send a plain-text message

For a message that does not need HTML, disable HTML mode and set the body directly:

$mail->isHTML(false);
$mail->Subject = 'Password reset requested';
$mail->Body = "Use this one-time link to reset your password:\n" . $resetUrl;

Attachment safety

  • Build attachment paths on the server; never accept an arbitrary filesystem path from a request.
  • Check that the file is readable and within an allowed size.
  • Use a safe download or storage workflow for uploaded files before attaching them.
  • Do not expose SMTP credentials, attachment paths, or detailed transport errors to visitors.

Production delivery checklist

  • Configure SPF, DKIM, and DMARC for the sending domain.
  • Use TLS and authenticated SMTP.
  • Queue email so a slow mail server does not delay the web request.
  • Rate-limit forms and notifications that can trigger messages.
  • Log failures privately and monitor bounces and complaints.
  • Escape or template dynamic values before inserting them into HTML.

See the official PHPMailer repository for provider-specific examples and configuration options.

admin

admin

Leave a Reply

Your email address will not be published.