PHP Email Validation: Filters and Verification

Published Updated

To validate an email address in PHP, pass it to filter_var() with FILTER_VALIDATE_EMAIL. The filter checks the address format. It does not tell you whether the mailbox exists or belongs to the person submitting the form.

For an account signup, send a confirmation link as well. For a mailing list, ask for consent separately. A correctly formatted address does not establish either ownership or permission to send marketing email.

For the rest of a registration form, see form and spelling validation in PHP after this. If the accepted address needs a message, continue to sending email in PHP.

How Do You Validate an Email Address in PHP?

Validate an email address in PHP with filter_var() and FILTER_VALIDATE_EMAIL after trimming surrounding whitespace. Reject an empty value before checking its syntax:

<?php

function validateEmailAddress(string $rawEmail): array
{
    $email = trim($rawEmail);
    $errors = [];

    if ($email === "") {
        $errors[] = "Enter an email address.";
    } elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        $errors[] = "Enter a valid email address.";
    }

    return [$email, $errors];
}

The function returns the trimmed address and a list of errors. An empty list means the address passed PHP’s syntax check. Ask users to correct invalid input rather than silently removing characters, which could change the address.

Use the Function in a Form Handler

A form handler can validate the email address before saving it. This example assumes validateEmailAddress() and saveSignup() are loaded, db() returns a configured PDO connection, and views/signup.php renders the form and escapes any displayed input:

<?php

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $rawEmail = $_POST["email"] ?? "";
    [$email, $errors] = validateEmailAddress(is_string($rawEmail) ? $rawEmail : "");

    if ($errors !== []) {
        require __DIR__ . "/../views/signup.php";
        return;
    }

    saveSignup(db(), $email);

    header("Location: /check-your-email", true, 303);
    return;
}

require __DIR__ . "/../views/signup.php";

The 303 redirect keeps the browser from resubmitting the form on refresh. That little pattern is still worth using for signups, password resets, profile updates, and any other POST request that changes state.

Store Through a Prepared Statement

Store the email address with a prepared statement. Email validation does not replace SQL parameter binding:

<?php

function saveSignup(PDO $pdo, string $email): void
{
    $statement = $pdo->prepare(
        "INSERT INTO newsletter_signups (email, created_at)
         VALUES (:email, CURRENT_TIMESTAMP)",
    );

    $statement->execute(["email" => $email]);
}

If the address must be unique, add a database constraint. This example uses PostgreSQL syntax:

CREATE TABLE newsletter_signups (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    email TEXT NOT NULL UNIQUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

The database constraint also prevents two simultaneous signup requests from inserting the same address. Handle a duplicate-address error in your form response.

How Do You Confirm That a User Owns an Email Address?

Confirm access to an email address by sending a unique, expiring link and requiring the recipient to follow it. Syntax validation alone cannot establish who receives the messages:

<?php

function createConfirmationToken(): string
{
    return bin2hex(random_bytes(32));
}

Store a hash of the token, send the raw token in the confirmation URL, and expire it. The validation step says "this looks like an email address." The confirmation step says "the user can receive mail at this address right now." Treat those as separate promises in the code, especially for account creation, password resets, and anything that could expose private data to the wrong inbox.

Should You Use Regex for PHP Email Validation?

Use PHP’s built-in email filter rather than writing a general email-validation regex. Add separate checks for application rules, such as allowing only a company domain:

<?php

function isCompanyEmail(string $email): bool
{
    return str_ends_with(strtolower($email), "@example.com");
}

That function answers a product question: is this address in the allowed domain? It does not try to replace PHP's email syntax filter.

Use the built-in filter for syntax, prepared statements for database writes, and confirmation links for mailbox ownership.

Frequently Asked Questions

Should an email address be lowercased before storing it?

You can lowercase the domain of an email address because domain names are case-insensitive. Preserve the part before the at sign unless your application has an explicit normalization policy; email standards allow that part to be case-sensitive.

Does PHP FILTER_VALIDATE_EMAIL accept plus-addressed emails?

PHP FILTER_VALIDATE_EMAIL accepts plus-addressed emails such as name+news@example.com. Do not remove the plus sign or reject the address just because it contains one.

Is there a maximum length for an email address?

An email address used in SMTP is generally limited to 254 octets, or bytes, including the at sign. For ASCII addresses that is 254 characters; international addresses need additional encoding and provider checks. Reject oversized input rather than silently truncating it.

Does PHP FILTER_VALIDATE_EMAIL accept email subdomains?

PHP FILTER_VALIDATE_EMAIL accepts email domains with subdomains, such as name@mail.example.com, when the complete address meets its syntax and length rules.

Does PHP email validation prove that a mailbox exists?

PHP FILTER_VALIDATE_EMAIL checks email syntax without contacting the domain or mailbox. A confirmation link lets you check that the user can receive mail at that address and follow the link.

Sources

  1. [1]
  2. [2]
  3. [3]
    PHP trim
    (php.net)
  4. [4]
    Input Validation Cheat Sheet
    (cheatsheetseries.owasp.org)