How7o
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Reading: How to Validate an Email Address in PHP
Share
How7oHow7o
Font ResizerAa
  • OS
Search
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Follow US
© 2024–2026 How7o. All rights reserved.
How7o > Free Laravel, PHP, WordPress & Server Tutorials > Web Development > How to Validate an Email Address in PHP
Web Development

How to Validate an Email Address in PHP

how7o
By how7o
Last updated: May 23, 2026
5 Min Read
Validate an email address in PHP with filter_var
SHARE

To validate an email address in PHP, use the built-in filter_var($email, FILTER_VALIDATE_EMAIL). It implements the actual email spec correctly and handles edge cases a hand-rolled regex doesn’t. For “does this email’s domain accept mail?” add a checkdnsrr on the domain’s MX records.

Contents
  • The one-liner
  • Check the domain has mail records
  • Why a regex is a worse choice
  • Normalise before storing
  • Confirm by sending
  • Frequently asked questions
  • Related guides
  • References

Last verified: 2026-05-17 on PHP 8.3. Originally published 2023-01-29, rewritten and updated 2026-05-17.

The one-liner

if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
    // syntactically valid
}

FILTER_VALIDATE_EMAIL returns the email itself on success, false on failure — so the result is truthy iff the address is valid syntax. Use it as the boolean for an if.

PHP email validation — filter_var, MX record check via checkdnsrr, normalize lowercase domain

Check the domain has mail records

$email  = '[email protected]';
$domain = substr( strrchr( $email, '@' ), 1 );

if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) && checkdnsrr( $domain, 'MX' ) ) {
    // syntactically valid AND domain accepts mail
}

checkdnsrr($domain, 'MX') queries DNS for an MX record. Returns true if the domain has one (or a fallback A record per RFC), false if the domain doesn’t exist. Catches typos like example.cmo that pass syntax but won’t deliver.

Why a regex is a worse choice

// The "good enough" regex you'll see in many tutorials
if ( preg_match( '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $email ) ) {
    // ...
}
  • Rejects valid emails with international characters (user@bücher.de after IDN normalisation).
  • Rejects IP-literal domains (user@[192.168.1.1]), which are valid per RFC.
  • Accepts some addresses that filter_var rejects (multiple dots in the local part, etc.).

Use filter_var — it’s been hardened against these edge cases.

Normalise before storing

function normalize_email( string $email ): ?string {
    $email = trim( $email );
    if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
        return null;
    }
    // Lowercase the domain (technically case-insensitive)
    [ $local, $domain ] = explode( '@', $email, 2 );
    return $local . '@' . strtolower( $domain );
}

Lowercase the domain so [email protected] and [email protected] aren’t treated as different users. Don’t touch the local part — it’s technically case-sensitive per RFC, even though most providers ignore case in practice.

Confirm by sending

The only way to verify the actual mailbox exists is to send something the user has to act on — a confirmation email with a tokenised link, magic-login URL, or one-time code. filter_var + checkdnsrr filters out garbage; the confirmation email proves the user owns the inbox. Most apps need both.

Frequently asked questions

Why is filter_var better than a regex?

FILTER_VALIDATE_EMAIL implements RFC 5321/5322 — the actual email standard. A handwritten regex like ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ rejects valid emails (international characters, + aliases in the local part for some patterns, IP-literal domains) and accepts some invalid ones. PHP’s built-in validator already handles the edge cases.

Does FILTER_VALIDATE_EMAIL check that the email exists?

No — it only validates syntax. The address could be perfectly formatted but point at a nonexistent inbox. To check existence: checkdnsrr($domain, 'MX') verifies the domain accepts mail. To verify the actual mailbox accepts your message, you have to send a verification email (the standard “click this link to confirm” flow) — there’s no reliable check that doesn’t involve sending.

Should I normalise email addresses before storing them?

Lowercase the domain (strtolower on the part after @). The local part is technically case-sensitive per RFC but in practice every mainstream provider treats it case-insensitively too — many normalise the whole address to lowercase to dedupe user accounts. Don’t strip +suffixes in the local part; [email protected] is intentional alias routing.

How do I validate emails on the client too?

<input type="email" required> — the browser does basic syntax validation. For the same regex-level check JS-side: /^\S+@\S+\.\S+$/.test(value) as a quick check, or duplicate the server-side filter via a fetch to a validation endpoint. Always re-validate server-side; client-side validation is UX, not security.

Related guides

  • How to Display PHP Errors
  • How to Remove Unwanted Characters from a String in PHP
  • How to Get the First Character of a String in PHP

References

PHP filter_var(): php.net/manual/en/function.filter-var.php. PHP FILTER_VALIDATE_EMAIL filter: php.net/manual/en/filter.filters.validate.php. PHP checkdnsrr(): php.net/manual/en/function.checkdnsrr.php.

TAGGED:phpSecurityValidation

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
[mc4wp_form]
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Copy Link Print
Previous Article Make Select2 work inside a Bootstrap modal How to Use Select2 Inside a Bootstrap Modal
Next Article Laravel unique validation that ignores the current record on update How to Validate a Unique Column on Update in Laravel
Leave a Comment

Leave a Reply Cancel reply

You must be logged in to post a comment.

FacebookLike
XFollow
PinterestPin
InstagramFollow
Most Popular
Run Laravel queue workers with Supervisor
How to Run Laravel Queue Workers in Production with Supervisor
May 23, 2026
Nginx as a reverse proxy for a Node.js app on Ubuntu
How to Set Up Nginx as a Reverse Proxy for Node.js on Ubuntu
May 23, 2026
Install and configure Redis on Ubuntu for Laravel and WordPress
How to Install and Configure Redis on Ubuntu (for Laravel & WordPress)
May 23, 2026
Harden a fresh Ubuntu VPS with UFW, Fail2Ban, and SSH key auth
How to Harden a Fresh Ubuntu VPS: UFW + Fail2Ban + SSH Key Auth
May 23, 2026
Set up Let's Encrypt SSL with Certbot on Ubuntu
How to Set Up Let’s Encrypt SSL with Certbot on Ubuntu (Apache & Nginx)
May 23, 2026

You Might Also Like

WordPress $wpdb->insert_id — read after $wpdb->insert or $wpdb->query INSERT
Web Development

How to Retrieve the Last Inserted Row ID in WordPress

7 Min Read
WooCommerce remove checkout fields — woocommerce_checkout_fields filter unsetting fields
Web Development

How to Remove Checkout Fields in WooCommerce

6 Min Read
Get the index in a jQuery each loop
Web Development

How to Get the Index in a jQuery .each() Loop

4 Min Read
WooCommerce get customer ID from order — WC_Order::get_user_id
Web Development

How to Get the Customer ID from an Order ID in WooCommerce

7 Min Read
How7o

We provide tips, tricks, and advice for improving websites and doing better search.

Tools

  • Age Calculator
  • Word Counter
  • Image Upscaler
  • Password Generator
  • QR Code Generator
  • See all tools→

Pranks

  • Fake Blue Screen Prank
  • Hacker Typer
  • Fake iMessage Generator
  • Windows XP Crash Prank
  • Windows 11 Update Prank
  • See all prank screens →

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service
  • Sitemap
© 2024–2026 How7o. All rights reserved.
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?