Email Systems

By the end of this lesson you'll send authenticated SMTP email from PHP with PHPMailer — HTML and plain-text, with attachments — queue large sends so they never block a request, and set up SPF, DKIM, and DMARC so your mail actually reaches the inbox.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Why mail() Is Not Enough

PHP ships with a mail() function, and it looks tempting because it's one line. But it hands your message to the server's local mail program with no authentication (no proof of who you are) and no encryption . Worse, it returns true the moment the message is handed off locally — that is not the same as the email being delivered. Gmail and Outlook routinely send mail() messages straight to spam, and you get no error explaining why.

The takeaway: a successful mail() call tells you almost nothing. For real, reliable email you need a proper SMTP connection — and that's what PHPMailer gives you.

2️⃣ Authenticated SMTP with PHPMailer

SMTP (Simple Mail Transfer Protocol) is the language mail servers speak. PHPMailer is the most popular PHP library for it — install it once with composer require phpmailer/phpmailer . It connects to a real mail server with a username and password (authentication) over a TLS -encrypted channel, so your mail is trusted and private. Notice the password comes from getenv() — never written in the code — and every send is wrapped in try/catch so a failure is handled, not ignored.

Two details that matter for the inbox: isHTML(true) sends a styled HTML message, and AltBody provides a plain-text fallback for clients that block HTML. Always set both — HTML-only mail is more likely to be flagged as spam.

3️⃣ Attachments, CC & BCC

Transactional email often carries a file — an invoice, a receipt, a ticket. PHPMailer makes this one call: addAttachment(path, name) reads a file from disk and gives it a clean display name. You can also copy other people in: addCC() adds a visible copy, while addBCC() adds a hidden one the other recipients can't see.

4️⃣ Sending to Many — Queue, Don't Block

An SMTP round-trip takes 1–3 seconds . If you send email during a web request, the user waits the whole time — and a newsletter to 1,000 people would time out completely. The fix is a queue : during the request you do a fast database write to record the job, then return immediately. A separate background worker (a script you run on a schedule, like php worker.php ) pulls jobs off the queue and does the slow sending out of the user's way.

Now you try. The SMTP setup below is almost complete — fill in each ___ using the 👉 hint, then check it against the Output panel.

One more. This HTML email needs a plain-text fallback so it isn't flagged as spam. Add the missing AltBody .

5️⃣ Deliverability: SPF, DKIM & DMARC

Even perfect PHPMailer code lands in spam if your domain doesn't vouch for it. Three DNS TXT records do that. SPF lists which servers may send for your domain. DKIM adds a cryptographic signature proving the message wasn't tampered with. DMARC tells receivers what to do when SPF or DKIM fail (e.g. quarantine), and where to email reports. Set all three and your deliverability jumps dramatically.

DNS records to add (example)

In practice you rarely manage all of this yourself. Transactional email providers — SendGrid, Mailgun, Amazon SES, Postmark — maintain trusted sending IPs, sign DKIM for you, and give you analytics, bounce handling, and webhooks. You simply point PHPMailer at their SMTP host (or call their API). For production, this is almost always the right call.

📋 Quick Reference — Email Systems

No code is filled in this time — just a brief and an outline. Write the function yourself, then run it on your own server with PHPMailer installed and an SMTP account configured. This is the exact helper you'll reuse across a real application.

Practice quiz

Why is PHP's built-in mail() function unreliable for real applications?

  • It can only send plain-text emails, never HTML
  • It is deprecated and removed in PHP 8.4
  • It hands the message to the local mail program with no SMTP authentication or encryption, so receivers distrust it and it often lands in spam
  • It always throws an exception you must catch

Answer: It hands the message to the local mail program with no SMTP authentication or encryption, so receivers distrust it and it often lands in spam. mail() has no auth and no encryption, and returns true once the message is merely handed off locally — not when it is actually delivered.

In the PHPMailer setup, which port is used for STARTTLS submission?

  • 587
  • 25
  • 465
  • 8080

Answer: 587. Port 587 is the submission port used with STARTTLS; 465 is implicit TLS and 25 is server-to-server (usually blocked for sending).

Where should the SMTP password come from in the PHPMailer examples?

  • Hardcoded directly in the source file
  • From a public URL fetched at runtime
  • From the email subject line
  • From the environment, e.g. getenv("SMTP_PASSWORD")

Answer: From the environment, e.g. getenv("SMTP_PASSWORD"). Secrets are read from the environment with getenv() and never written into the code, where they would leak the moment the file is shared or committed.

What is the purpose of PHPMailer's AltBody property?

  • It sets the email's subject line
  • It provides a plain-text fallback for clients that block HTML, which also improves spam scores
  • It attaches a file to the message
  • It hides the recipient from other recipients

Answer: It provides a plain-text fallback for clients that block HTML, which also improves spam scores. Always set both Body (HTML) and AltBody (plain text) — HTML-only mail is more likely to be flagged as spam.

Which PHPMailer method adds a HIDDEN copy that other recipients cannot see?

  • addBCC()
  • addCC()
  • addAddress()
  • addAttachment()

Answer: addBCC(). addBCC() adds a hidden copy; addCC() adds a visible one.

Why should bulk email sends be queued instead of sent during the web request?

  • Because mail providers ban sending from web requests
  • Because queued emails skip spam filters
  • Because an SMTP round-trip takes 1–3 seconds, so sending in-request makes the user wait and can time out
  • Because PHPMailer cannot run inside a request

Answer: Because an SMTP round-trip takes 1–3 seconds, so sending in-request makes the user wait and can time out. Queue the job with a fast DB write and let a background worker do the slow SMTP sending, so the response returns instantly.

What does the SPF DNS record do for email deliverability?

  • It encrypts the message body
  • It lists which servers are allowed to send mail for your domain
  • It adds a cryptographic signature to each message
  • It tells receivers what to do when checks fail

Answer: It lists which servers are allowed to send mail for your domain. SPF lists permitted sending servers; DKIM signs the message; DMARC says what to do when SPF or DKIM fail.

What does the DKIM record add to an outgoing email?

  • A list of allowed sending IP addresses
  • A queue priority level
  • The plain-text fallback body
  • A cryptographic signature proving the message wasn't altered

Answer: A cryptographic signature proving the message wasn't altered. DKIM adds a cryptographic signature so receivers can confirm the message wasn't tampered with in transit.

Passing new PHPMailer(true) does what?

  • Enables HTML mode automatically
  • Turns on exceptions so failures can be caught with try/catch and read from $mail->ErrorInfo
  • Sends the email immediately
  • Disables TLS encryption

Answer: Turns on exceptions so failures can be caught with try/catch and read from $mail->ErrorInfo. The true argument enables exceptions; without it you get 'SMTP connect() failed' with no detail.

Why use a transactional provider like SendGrid, Mailgun, or Amazon SES?

  • They let you skip writing any PHP code
  • They make mail() reliable again
  • They maintain trusted sending IPs, handle SPF/DKIM signing, and scale to millions of emails
  • They are the only way to send attachments

Answer: They maintain trusted sending IPs, handle SPF/DKIM signing, and scale to millions of emails. Providers handle IP reputation, DKIM signing, analytics, and scale — you just point PHPMailer at their SMTP host.