Ensuring Proper Email Validation in PHP: Avoiding False Positives

Ensuring Proper Email Validation in PHP: Avoiding False Positives
Photo by Erik Karits / Unsplash

When working with email validation in PHP, you might assume that using FILTER_VALIDATE_EMAIL is enough. However, this built-in filter can sometimes allow invalid email formats, leading to unexpected issues in your application. A common example is a string like +44112233, which is clearly not an email, yet PHP may not flag it as invalid.

Why FILTER_VALIDATE_EMAIL Alone Is Not Enough

PHP's filter_var($email, FILTER_VALIDATE_EMAIL) function only checks for a valid email syntax based on the RFC 822 standard. However, this standard is quite broad, allowing many unusual formats that are technically valid but not suitable for real-world applications.

For example:

$email = "+44112233";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "Valid email";
} else {
    echo "Invalid email";
}

The above incorrectly considers +44112233 to be valid because, under RFC rules, it can be interpreted as a valid email with an implicit domain. This is a problem!

A More Robust Email Validation Approach

To avoid such issues, you should combine FILTER_VALIDATE_EMAIL with a regular expression to enforce a stricter format. A better approach is:

$email = "+44112233";

if (!filter_var($email, FILTER_VALIDATE_EMAIL) || !preg_match('/^[^@]+@[^@]+\.[a-zA-Z]{2,}$/', $email)) {
    echo "Invalid email format";
} else {
    echo "Valid email";
}
💡
Live demo here.

Breaking Down the Improved Validation

  1. FILTER_VALIDATE_EMAIL – Ensures basic email structure is present.
  2. Regular expression (preg_match) – Checks if the email contains an @ symbol and a valid domain (example.com).
    • [^@]+@[^@]+\.[a-zA-Z]{2,}$ ensures that:
      • There is at least one character before the @.
      • A domain name exists after @.
      • The domain contains a dot (.) followed by at least two letters (TLD).

Additional Considerations for Email Validation

  1. Disposable Emails: Some users use temporary/disposable emails. You can integrate an API or maintain a blacklist to prevent such emails.
  2. Length Limits: RFC 5321 states that an email address should be no more than 320 characters long.
  3. Allowing Internationalized Domains: If your application supports internationalized domain names (IDN) (e.g., jörg@exämple.de), consider using idn_to_ascii() to normalize the domain before validation.

DNS Verification: Checking only the format is not enough; you should verify that the domain exists using checkdnsrr().

function isValidEmail($email) {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
    $domain = substr(strrchr($email, "@"), 1);
    return checkdnsrr($domain, "MX");
}

This ensures that the domain has a valid Mail Exchange (MX) record, meaning emails can be received.

Finally

While PHP provides a built-in function for email validation, it is not always strict enough for real-world applications. Combining it with regular expressions, DNS validation, and other checks ensures better accuracy and prevents invalid emails from passing through. By implementing a more robust validation strategy, you can improve data integrity and reduce errors in user input.

Support Us