Codeskill

Learn to code, step by step

Mail and notifications without painting yourself into a corner

Mail and notifications from PHP without painting yourself into a corner. Contact forms, password resets, and ‘your order shipped’ emails all need the same basic plumbing. Is one of those topics that pays off as soon as you use it on a real page.

mail() vs SMTP library

mail() works on some hosts and fails silently on others. For anything serious, use SMTP via PHPMailer or Symfony Mailer (both installable with Composer). For local dev, log emails instead of sending.

Interface + log implementation (recap)

You already saw MailerInterface in the OOP tutorial. Keep that pattern: production gets SMTP, local gets a log mailer.

// LogMailer writes to storage/logs/mail.log
// SmtpMailer wraps PHPMailer or similar

HTML email basics

Send multipart emails (plain text + HTML) so clients that strip HTML still show something readable. Keep HTML simple – tables for layout still dominate email clients.

Password reset flow

  • User submits email on ‘forgot password’ form
  • Generate a random token, store a hash and expiry in the database
  • Email a link with the token: /reset-password?token=…
  • On submit, verify token, update password hash, invalidate token
$token = bin2hex(random_bytes(32));
$hash = hash('sha256', $token);
$expires = date('Y-m-d H:i:s', time() + 3600);

// Store $hash and $expires for the user row or a password_resets table
// Email contains the raw $token in the URL (not the hash)

Do not leak information

Password reset forms should say ‘If that email exists, we sent a link’ whether or not the account exists. Same rule as login errors.

Queue later (concept)

Sending mail inside a web request slows the page down. When the app grows, push mail jobs to a queue and process them in a CLI script. That is advanced territory – but design your mailer behind an interface now so the swap is easy.

Build mail once, behind an interface, with a log driver for local work. You will thank yourself when SMTP credentials differ on every host.

PreviousFile uploads securely