Send Email Code in PHP: Build a Reliable Mailer in 6 Steps

Santaji GadePHPDevelopmentYesterday7 Views

send email code in php

Write reliable send email code in PHP with PHPMailer and SMTP authentication, covering HTML emails, attachments, error handling, and safe testing.

Development PHP Email SMTP

A contact form that quietly fails to deliver its emails is worse than no form at all, because nobody finds out until a customer complains somewhere else. Send email code in PHP done properly means SMTP, authentication, and a way to know when a message actually failed.

01

Why Send Email Code in PHP Needs More Than the mail Function

PHP ships with a built in mail() function, and it looks like the obvious starting point for sending a message from a form.

In practice it depends on the server having a working local mail transfer agent configured, which many shared hosts either skip or configure poorly.

Messages sent through a poorly configured mail() call also tend to land in spam, since they usually skip proper authentication headers entirely.

An SMTP library talking directly to a real mail provider avoids both problems, which is why most working PHP applications reach for one instead.

02

Choosing How to Send Mail From PHP

Three realistic options cover almost every PHP project, and picking between them mostly comes down to how much control the app needs over delivery.

ApproachReliabilityBest For
Built in mail() functionDepends entirely on server configurationQuick local testing only
PHPMailer over SMTPReliable, authenticated deliveryMost production applications
Transactional email API (SendGrid, Mailgun)Very reliable, includes analyticsHigh volume or marketing style sending

This guide builds around PHPMailer, the most widely used SMTP library in the PHP ecosystem, since it fits both a small contact form and a larger notification system. Both SendGrid and Mailgun also publish their own PHP quickstarts, worth comparing once send volume grows past what shared SMTP handles well.

03

Installing PHPMailer With Composer

Composer is the standard way to pull PHPMailer into a project, and it also handles autoloading so nothing needs a manual include path.

terminal
# install PHPMailer through Composer
composer require phpmailer/phpmailer

If the project has no composer.json yet, running composer init first creates one, and PHPMailer becomes the first real dependency listed inside it.

04

Writing a Basic Send Email Function

A single reusable function keeps SMTP configuration in one place instead of scattered across every form handler that needs to send a message.

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

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

function send_notification_email($to, $subject, $body) {
    $mail = new PHPMailer(true);

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

        $mail->setFrom('noreply@brandella.in', 'Brandella Journal');
        $mail->addAddress($to);
        $mail->Subject = $subject;
        $mail->Body = $body;

        $mail->send();
        return true;
    } catch (Exception $e) {
        error_log("Mail failed: " . $mail->ErrorInfo);
        return false;
    }
}

Reading credentials with getenv() instead of hardcoding them keeps a real password out of version control entirely. Gmail also requires an app password rather than the normal account password once two factor authentication is turned on.

05

Sending HTML Emails With Dynamic Content

Plain text is fine for a simple alert, but most real notifications benefit from formatting, a logo, and a clear call to action.

html_mailer.php
$mail->isHTML(true);
$mail->Subject = 'Your order has shipped';
$mail->Body = sprintf(
    '<h2>Thanks, %s</h2><p>Order #%s is on its way.</p>',
    htmlspecialchars($customer_name),
    htmlspecialchars($order_id)
);
$mail->AltBody = sprintf('Thanks, %s. Order #%s is on its way.', $customer_name, $order_id);

htmlspecialchars() around any value that came from a user matters here, since an unescaped name field is a real injection risk inside an HTML email body.

Setting AltBody gives email clients that block HTML a readable plain text fallback instead of a blank or broken message.

06

Adding Attachments

An invoice, a receipt, or a generated report often needs to travel with the email rather than living behind a separate download link.

attachment.php
$mail->addAttachment('/tmp/invoice_1042.pdf', 'Invoice.pdf');

PHPMailer reads the file straight from disk, so anything generated moments earlier by an invoice script can be attached without an extra upload step.

07

Handling Errors and Delivery Failures

A send that fails silently is the exact problem this whole approach is meant to fix, so failures need to surface somewhere a developer will actually see them.

error_handling.php
$mail->SMTPDebug = 0;

if (!send_notification_email($to, $subject, $body)) {
    error_log(sprintf('Notification to %s failed at %s', $to, date('c')));
}

Logging the recipient and timestamp on failure turns a silent problem into something a support ticket or a monitoring alert can actually catch. This is the part of send email code in PHP that most tutorials skip, and it is usually the part that saves a debugging session later.

08

Testing Emails Safely Before Going Live

Sending real test emails to a real inbox during development is how a test message ends up in front of an actual customer by accident.

A tool like Mailtrap catches outgoing SMTP traffic in a safe sandbox inbox, so every send during development can be inspected without ever leaving the test environment.

  • Swap SMTP credentials by environment: point at Mailtrap locally and the real provider in production through environment variables, never a hardcoded host.
  • Check the AltBody every time: a broken plain text fallback is easy to miss since most developers only ever look at the HTML version.
  • Rate limit outgoing mail: a loop that sends hundreds of emails without pacing can trip a provider's spam protection mid batch.
  • Verify SPF and DKIM on the sending domain: authentication records matter as much as the code, since even perfect code cannot fix a missing DNS record.
  • Never log a full email body with personal data: log the recipient and status, not the message contents, to avoid storing sensitive information in a log file.
09

Watch: Sending Email With PHPMailer

Codecourse walks through a working PHPMailer setup end to end, which pairs well with the environment variable pattern used throughout this guide.

Video credit: Codecourse.

Seeing the SMTP handshake fail and succeed on screen makes the try and catch block in the code above much easier to reason about.

Form Submission PHPMailer SMTP Auth Inbox Delivery

Frequently Asked Questions

It depends on local server configuration that is often missing or incomplete, and messages sent through it commonly land in spam because they lack proper authentication.

PHPMailer configured for SMTP with a real provider like Gmail, SendGrid, or Mailgun is the most reliable starting point, since it handles authentication and delivery details the built in function does not.

Yes. Calling addAddress multiple times adds more recipients, and addBCC or addCC work the same way for blind copies and carbon copies.

Authenticate through a real SMTP provider, set up SPF and DKIM records for the sending domain, and avoid spam trigger words in the subject line.

No. Environment variables or a properly excluded configuration file keep credentials out of version control, which matters even for a small internal project.

What We Learn Today

1

mail() is not reliable enough

Server configuration and missing authentication headers make it a poor production choice.

2

SMTP beats local mail transfer

Authenticating with a real provider gets messages delivered instead of flagged.

3

HTML needs a plain text fallback

AltBody keeps the message readable for clients that block HTML.

4

Errors must be visible

A silent failure defeats the entire purpose of sending a notification.

5

Testing needs a sandbox

A tool like Mailtrap keeps test sends away from real inboxes.

6

DNS matters as much as code

SPF and DKIM records affect delivery just as much as the script itself.

Ready to Send Reliable Email From PHP?

Pair send email code in PHP with a wider toolkit to keep every notification landing where it should.

0 Votes: 0 Upvotes, 0 Downvotes (0 Points)

Leave a reply

Loading Next Post...
Search
Popular Now
Loading

Signing-in 3 seconds...

Signing-up 3 seconds...