Skip to content

Instantly share code, notes, and snippets.

@justinmassiot
Last active December 13, 2023 17:13
Show Gist options
  • Save justinmassiot/bfdd9d95eea5eb60f038ae077aa22f3c to your computer and use it in GitHub Desktop.
Save justinmassiot/bfdd9d95eea5eb60f038ae077aa22f3c to your computer and use it in GitHub Desktop.
<?php
/**
*
* PHP EMAIL VALIDATION
* This script performs real time email verification.
*
* @author Rowland O'Connor <https://plus.google.com/+RowlandOConnor>
* @version 1.0.0
*
* IMPORTANT DISCLAIMER
* This script is provided AS IS for educational purposes only.
*
* Script is NOT designed for industrial application and has
* several known key deficiencies in error tolerance
* and accuracy / coverage of email address queries.
*
* No warranty or support is provided. Use of this script
* is at your own risk.
*
*
* USAGE WARNING
* Many hosting companies do not allow SMTP send
* operations. Please get permission from your hosting provider
* before deploying this script.
*
*
* LICENSE
* This script is licensed under Apache 2.0 (http://www.apache.org/licenses/).
*
*
* For further details, please see accompanying readme.txt.
*
*
* Source code at
* https://github.com/Roly67/php-email-validation
*/
?>
<?php
/* CONFIGURATION */
/*
$FROM Appears in the MAIL FROM:<> part of the SMTP conversation
It is VITAL to set this to your valid domain otherwise email
verification might not work.
*/
$FROM = "[email protected]"; // <-- !VERY, VERY, IMPORTANT. DON'T FORGET TO SET.
/*
$EMAIL_REGEX is used for Regex validation of the email address.
You can use your own, but the default one below is pretty comprehensive
and should be good enough for most purposes.
*/
$EMAIL_REGEX="^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$";
/*
$TCP_BUFFER_SIZE defines the in memory buffer size used for SMTP conversations.
Default of 1024 is fine in most cases.
*/
$TCP_BUFFER_SIZE = 1024;
?>
<?php
/*
Presentation HTML
*/
?>
<p><strong><a href="https://github.com/Roly67/php-email-validation" target="_blank">PHP Email Validation</a></strong> script.</p>
<p>Example script to verify emails in real time using <abbr title="Personal Home Page">PHP</abbr>.</p>
<p><strong>Notes:</strong></p>
<ul>
<li>Provided &quot;as is&quot; for educational purposes only.</li>
<li>
Performs two layers of validation:
<ol>
<li><strong>Syntax</strong> using server side regular expression.</li>
<li><strong><abbr title="Simple Mail Transfer Protocol">SMTP</abbr></strong> connects to remote mail servers.</li>
</ol>
</li>
<li>Source code and documentation at <a href="https://github.com/Roly67/php-email-validation" target="_blank" rel="nofollow">Github</a></li>
</ul>
<form action="" method="get">
<input type="text" id="emailtoverify" name="emailtoverify" value="<?php if(isset($_GET["emailtoverify"]))
echo($_GET["emailtoverify"])?>" />
<input type="submit" value="verify" />
</form>
<?php
/*POST back handler*/
if(isset($_GET["emailtoverify"]))
{
$result = VerifyMail(trim($_GET["emailtoverify"]));
// SMTP code 250 shows email is valid.
if (substr($result[0],0,3) == "250")
echo("<strong>Result</strong>: Email is OK");
else
{
echo("<strong>Result</strong>: Email is bad");
// The reason why it's bad.
echo("<br/><br/> <strong>Description</strong>: ".$result[0]);
}
echo("<p><strong>Server log:</strong></p>");
$log = $result[2];
$log = str_replace("<","&lt;", $log);
$log = str_replace(">","&gt;", $log);
$log = str_replace("\r","<br/>", $log);
echo($log);
}
/*
Description:
Verifies email address
Parameters:
$Email - Email address to verify
Returns:
Array containing email verification result.
*/
function VerifyMail($Email)
{
global $FROM; // FROM address. See settings section above
global $EMAIL_REGEX; // Email syntax verification Regex
global $TCP_BUFFER_SIZE; //TCP buffer size for mail server conversation.
// $HTTP_HOST gets the host name of the server running the PHP script.
$HTTP_HOST = $_SERVER["HTTP_HOST"];
// Prep up the function return.
$Return = array();
// Do the syntax validation using simple regex expression.
// Eliminates basic syntax faults.
if (!preg_match("/$EMAIL_REGEX/i", $Email))
{
$Return[0] = "Bad Syntax";
return $Return;
}
// load the user and domain name into a local list from email address using string split function.
list ( $Username, $Domain ) = explode ("@",$Email);
// check if domain has MX record(s)
if ( checkdnsrr ( $Domain, "MX" ) )
{
$log .= "MX record for {$Domain} exists.\r";
// Get DNS MX records from domain
if ( getmxrr ($Domain, $MXHost))
{
}
// Get the IP address of first MX record
$ConnectAddress = $MXHost[0];
// Open TCP connection to IP address on port 25 (default SMTP port)
$Connect = fsockopen ( $ConnectAddress, 25 );
// Rerun array element index 1 contains the IP address of the target mail server
$Return[1] = $ConnectAddress;
// Successful connection to mail server.
if ($Connect)
{
$log .= "Connection to {$ConnectAddress} SMTP succeeded.\r";
// look for a response code of 220 using Regex
if ( ereg ( "^220", $reply = fgets ( $Connect, $TCP_BUFFER_SIZE ) ) )
{
$log .= $reply."\r";
// Start SMTP conversation with HELO
fputs ( $Connect, "HELO ". $HTTP_HOST ."\r\n" );
$log .= "> HELO ". $HTTP_HOST ."\r";
$reply = fgets ( $Connect, $TCP_BUFFER_SIZE );
$log .= $reply."\r";
// Next, do MAIL FROM:
fputs ( $Connect, "MAIL FROM: <". $FROM .">\r\n" );
$log .= "> MAIL FROM: <". $FROM .">\r";
$reply = fgets ( $Connect, $TCP_BUFFER_SIZE );
$log .= $reply."\r";
// Next, do RCPT TO:
fputs ( $Connect, "RCPT TO: <{$Email}>\r\n" );
$log .= "> RCPT TO: <{$Email}>\r";
$to_reply = fgets ( $Connect, $TCP_BUFFER_SIZE );
$log .= $to_reply."\r";
// Quit the SMTP conversation.
fputs ( $Connect, "QUIT\r\n");
// Close TCP connection
fclose($Connect);
}
}
else
{
// Return array element 0 contains a message.
$Return[0]="500 Can't connect mail server ({$ConnectAddress}).";
return $Return;
}
}
else
{
$to_reply = "Domain '{$Domain}' doesn't exist.\r";
$log .= "MX record for '{$Domain}' doesn't exist.\r";
}
$Return[0]=$to_reply;
$Return[2]=$log;
return $Return;
}
?>
# Pre-requisite: `pip install dnspython`
# Source: https://github.com/scottbrady91/Python-Email-Verification-Script
import re
import smtplib
import dns.resolver
# Address used for SMTP MAIL FROM command
fromAddress = '[email protected]'
# Simple Regex for syntax checking
regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$'
# Email address to verify
inputAddress = input('Please enter the emailAddress to verify:')
addressToVerify = str(inputAddress)
# Syntax check
match = re.match(regex, addressToVerify)
if match == None:
print('Bad Syntax')
raise ValueError('Bad Syntax')
# Get domain for DNS lookup
splitAddress = addressToVerify.split('@')
domain = str(splitAddress[1])
print('Domain:', domain)
# MX record lookup
records = dns.resolver.query(domain, 'MX')
mxRecord = records[0].exchange
mxRecord = str(mxRecord)
# SMTP lib setup (use debug level for full output)
server = smtplib.SMTP()
server.set_debuglevel(0)
# SMTP Conversation
server.connect(mxRecord)
server.helo(server.local_hostname) ### server.local_hostname(Get local server hostname)
server.mail(fromAddress)
code, message = server.rcpt(str(addressToVerify))
server.quit()
#print(code)
#print(message)
# Assume SMTP response 250 is success
if code == 250:
print('Success')
else:
print('Bad')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment