Email is undoubtedly one of the key details you collect about your users. Therefore, validating these email addresses is one of the most common things you do in your web application and like many other things in PHP, emails can be validated in more than one way. In this tutorial, we’ll show you the various methods to validate an email address with PHP.

Regex to the Rescue

We can generate a regex for an email according to the RFC-5322 Official Standard that is around 99.99% accurate. Note that there is no perfect regex for email, hence, the 99.99% accuracy.

Regular Expression

The following is the regular expression that determines the validity of a given email address.

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Email Regex Diagram
Railroad diagram of the regex

Using Regex in PHP

Using the regular expression that we defined earlier, we can use it in PHP to validate email addresses. Here’s how you can do it:

/**
 * Returns true if specified input email is valid
 * @param  String  $email email address
 * @return boolean is $email a valid email address or not
 */
public function isEmailValid($email)
{
    //check if email is an array or numeric or boolean or float or a file,directory or an integer
    if(is_array($email) || is_numeric($email) || is_bool($email) || is_float($email) || is_file($email) || is_dir($email) || is_int($email))
        return false;
    else
    {
        //remove whitespaces and 
        //convert email to loweercase for processing
        $email=trim(strtolower($email));

        //regex
        $pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD';

        //compare email with regex
        return (preg_match($pattern, $email) === 1) ? $email : false;
    }
}

In the method defined above, we take the email as the input and run it through some basic checks to verify if the input passed is not an array, number, boolean, a decimal, or a file.

We then use PHP’s preg_match( ) to perform a regex match and check if the given string matches the specified pattern. In this case, it checks whether the given string is a valid string email address.

Use filter_var() to Validate Email Addresses with PHP

PHP’s filter_var() method filters a given input with the specified filters. There a number of filters available, such as FILTER_VALIDATE_BOOLEAN , FILTER_VALIDATE_DOMAIN , FILTER_VALIDATE_EMAIL etc.

/**
 * Returns true if specified input email is valid
 * @param  String  $email email address
 * @return boolean        is $email a valid email address or not
 */
public function isEmailValid($email)
{
    //check if email is an array or numeric or boolean or float or a file,directory or an integer
    if(is_array($email) || is_numeric($email) || is_bool($email) || is_float($email) || is_file($email) || is_dir($email) || is_int($email))
        return false;
    else
    {
        //convert email to loweercase for processing
        $email=trim(strtolower($email));

        //Check if valida email
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return true;
        } else {
            return false;
        }
    }
}

We use similar checks initially that we did in the regex method. After that, we check if the email is valid or not by using filter_var() method with the FILTER_VALIDATE_EMAIL filter, which is a predefined filter to validate emails.

A better way to use filter_var()

There is another lesser-known validator to email. FILTER_SANITIZE_EMAIL removes all illegal and unsupported characters from the input. We can then pass this sanitized input to filter_var() function with the good old FILTER_VALIDATE_EMAIL filter.

/**
 * Returns true if specified input email is valid
 * @param  String  $email email address
 * @return boolean        is $email a valid email address or not
 */
public function isEmailValid($email) {
    $email = filter_var($email, FILTER_SANITIZE_EMAIL); 

    //Check if valid email
    if (filter_var($email, FILTER_VALIDATE_EMAIL)) { 
        return true; 
    }  
    else { 
        return false; 
    }
}

How to Validate an Email’s Existence

Validating just the email string does not guarantee that it actually exists. However, there are a couple of ways to tackle this issue.

Check if email’s domain is valid

We can add an additional check that validates if the domain associated with the email is valid or not. You can extract the domain name from an email address like so:

$email = "sapnesh@codezen.io"; 
$parts = explode("@",$email); 
$domain = $parts[1]; 
echo $domain // codezen.io

Now that we know how to extract the domain name from a string, we can integrate it in a new method that checks whether the email’s domain is valid:

/**
 * Verify if email's domain is valid.
 * @param  String  $email email id
 * @return boolean is email's domain valid or not
 */
public function isEmailDomainValid($email) {
    $parts = explode("@",$email);
    $domain = $parts[1];

    if (!checkdnsrr($domain, 'MX')) {
        return false;
    } else {
        return true;
    }
}

In the method defined above, we check if the domain name has an MX record associated with it. MX (Mail Exchange) records are DNS records that are necessary for email delivery. checkdnsrr() function is used to check DNS records of a hostname or an IP address.

Note: You can go a step even further by sending an OTP token with the email address or verification link. This is the best way to make sure the user’s email is valid and that actually they own the email address.

Try sending an email

We can actually try sending an email and see if it is successful. We will use PHP’s mail() function to send emails.

    /**
     * Sends a verification email
     * @param  String $email email address of the user
     * @return void does not return anything
     */
    public function sendEmail($email) {
        // the message
        $msg = "This email is to verify if your email is valid";

        // use wordwrap() if lines are longer than 70 characters
        $msg = wordwrap($msg, 70);

        //subject field of email
        $subject = "Verification Email";

        // send email
        mail($email, $subject, $msg);
    }

Validating Email Addresses in Laravel

If you are using a PHP framework, such as Laravel, then validating email addresses is a bit easier. You can use the email rune provided by Laravel’s Validation Class:

    public function validateEmail(Request $request) {
        $validator = Validator::make($request->all(), [
            'Email'=>'required|email'
        ]);

        if ($validator->fails()) {
            return abort(404);
        }
        // continue your logic
    }

Note: In Laravel, you can go a step further by automaticaly confirming a user’s email address. For details on implementation, see Laravel’s Email Verification page.

That’s it! These are the different ways you can validate email addresses in PHP. If you have any doubts, please ask them in the comment section below.

If you are a Laravel enthusiast like me, then you will definitely find these Laravel articles interesting.