PHP Email Validation - SMTP, MX Record 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);
</script>
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:
<?php
$email=’user@gmail.com’;
list($name, $domain)=explode('@',$email); if(!checkdnsrr($domain,'MX'))
return false;
else
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:
-
Sender: HELLO! I'm the sending mail server.
-
Receiver: Hello, I'm the receiving mail server. Go ahead!
-
Sender: Mail from: Somebody
-
Receiver: OK, that's good.
-
Sender: Mail to: Somebody else
-
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:
<?php
function smtp_validate($email){
$result=false;
list($name, $domain)=explode('@',$email); # SMTP QUERY CHECK
$max_conn_time = 30;
$sock='';
$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);
break;
} } # 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
$result=true;
}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;
}else{
$result=false;
} #quit smtp connection
$msg="quit"; fwrite($sock, $msg."\r\n"); # close socket
fclose($sock); }
return $result;
}
Note:
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)
Rahul Singh -
August 09, 2018
Its not working for all domains and email.
Sathisdhanasekaran -
July 07, 2018
it, works !.......... thanks for helping..............
Yogesh -
January 09, 2018
Can I implement it for bulk email checking?
WDS -
March 18, 2018
Yes, You can.
Rdlook04 -
December 18, 2017
This one works. pretty well. very skilled solution... thank you