We sometimes need to validate the integrity of given email id. The easiest way we have is just sending a verification mail to the given email id and asking the user to click on the link in that email. But other than that we have three more ways, that is, SMTP Email Validation, MX Record Check and  Regular Expression. Each has its own merits and demerits; we can look at each one of them.
Download php email validation script below which validates email using SMTP validation, mx record check and regular expression.

Regular Expression Check:

This is simple type of email validation and it’s done in client side. This method doesn’t check whether the email actually exist or not, but it simply checks given email is in standard form or not.

Example Code:

<script type='text/javascript'>
var valid_email='user@example.com';
var invalid_email='user@sdfd.c';
var em_filter=/^[_A-z0-9-]+((\.|\+)[_A-z0-9-]+)*@[A-z0-9-]+(\.[A-z0-9-]+)*(\.[A-z]{2,4})$/;

if (!em_filter.test(valid_email))
   alert('Email not valid: '+valid_email); if (!em_filter.test(invalid_email))
   alert('Email not valid: '+invalid_email);

MX Record Check:

Usually a mail server is configured to process emails for a domain. MX Record holds ip address of that mail server, just like a pointer. So by checking MX Records we can make sure whether this domain can process emails or not.

This will avoid providing emails with fault domain names, like user@gmai.lcom etc. But still we aren’t sure that the given email exist or not as we check only domain capabilities.

Example Code:

list($name, $domain)=explode('@',$email); if(!checkdnsrr($domain,'MX'))
   return false;
   return true;

SMTP Email Validation:

SMTP Email Validation done by communicating mail server through SMTP commands such as HELO, RCPT To etc. You can learn more about SMTP commands here. By checking reply code from mail server we can make sure whether given email exist or not.

We follow below order in validating email:

  1. Sender: HELLO! I'm the sending mail server.

  2. Receiver: Hello, I'm the receiving mail server. Go ahead!

  3. Sender: Mail from: Somebody

  4. Receiver: OK, that's good.

  5. Sender: Mail to: Somebody else

  6. Receiver: Okay, that's fine

For each command listed above, we receive a status code from reply server. In step 6, if we receive reply code as 250, then we can assume that email was accepted and it is exist. Even if the reply code is 450 / 451, we can still think that email exist, because these codes were sent when there is a temporary error in MTA or email gray listed.

Example Code:

function smtp_validate($email){
   list($name, $domain)=explode('@',$email);    # SMTP QUERY CHECK
   $max_conn_time = 30;
   $port = 25;
   $max_read_time = 5;
   $users=$name;    # retrieve SMTP Server via MX query on domain
   $hosts = array();
   $mxweights = array();
   getmxrr($domain, $hosts, $mxweights);
   $mxs = array_combine($hosts, $mxweights);
   asort($mxs, SORT_NUMERIC);    #last fallback is the original domain
   $mxs[$domain] = 100;
   $timeout = $max_conn_time / count($mxs);    # try each host
   while(list($host) = each($mxs)) {
      #connect to SMTP server
      if($sock = fsockopen($host, $port, $errno, $errstr, (float) $timeout)){
         stream_set_timeout($sock, $max_read_time);
      }   }   # did we get a TCP socket
  if($sock) {
      $reply = fread($sock, 2082);
      preg_match('/^([0-9]{3}) /ims', $reply, $matches);
      $code = isset($matches[1]) ? $matches[1] : '';       if($code != '220') {
         # MTA gave an error...
         return $result;
      }       # initiate smtp conversation
      $msg="HELO ".$domain;
      fwrite($sock, $msg."\r\n");
      $reply = fread($sock, 2082);       # tell of sender
      $msg="MAIL FROM: <".$name.'@'.$domain.">";       fwrite($sock, $msg."\r\n");
      $reply = fread($sock, 2082);       #ask of recepient
      $msg="RCPT TO: <".$name.'@'.$domain.">";       fwrite($sock, $msg."\r\n");
      $reply = fread($sock, 2082);       #get code and msg from response
      preg_match('/^([0-9]{3}) /ims', $reply, $matches);       $code = isset($matches[1]) ? $matches[1] : '';       if($code == '250'){
         #you received 250 so the email address was accepted
      }elseif($code == '451' || $code == '452') {
         #you received 451 so the email address was greylisted
         #or some temporary error occured on the MTA) - so assume is ok          $result=true;
      }       #quit smtp connection
      $msg="quit";       fwrite($sock, $msg."\r\n");       # close socket
      fclose($sock);   }
   return $result;

You may still get reply code as 250 from reply mail server when the server set to "catch all inbound messages", in that cases this smtp email validation goes inaccurate as it replies 250 even for non existent email.

Comments (5)
  1. Image
    Rahul Singh - Reply

    August 09, 2018

    Its not working for all domains and email.

  2. Image
    Yogesh - Reply

    January 09, 2018

    Can I implement it for bulk email checking?

    • Image
      WDS - Reply

      March 18, 2018

      Yes, You can.

  3. Image
    Rdlook04 - Reply

    December 18, 2017

    This one works. pretty well. very skilled solution... thank you

Leave a Comment

loader Posting your comment...