How to check if an email address is real or valid using PHP
I found some websites that claim to verify if email addresses are valid. Is it possible to check if an email address is valid using just PHP?
<?php
if($_POST['email'] != ''){
// The email to validate
$email = $_POST['email'];
// An optional sender
function domain_exists($email, $record = 'MX'){
list($user, $domain) = explode('@', $email);
return checkdnsrr($domain, $record);
}
if(domain_exists($email)) {
echo('This MX records exists; I will accept this email as valid.');
}
else {
echo('No MX record exists; Invalid email.');
}
}
?>
<form method="POST">
<input type="text" name="email">
<input type="submit" value="submit">
</form>
This is what I have right now. It checks if the domain exist, but it cannot check if the user's email exist on that domain. Is it possible to do that using PHP?
You should check with SMTP.
That means you have to connect to that email's SMTP server.
After connecting to the SMTP server you should send these commands:
HELO somehostname.com
MAIL FROM: <[email protected]>
RCPT TO: <[email protected]>
If you get "<[email protected]> Relay access denied" that means this email is Invalid.
There is a simple PHP class. You can use it:
http://www.phpclasses.org/package/6650-PHP-Check-if-an-e-mail-is-valid-using-SMTP.html
You can't verify (with enough accuracy to rely on) if an email actually exists using just a single PHP method. You can send an email to that account, but even that alone won't verify the account exists (see below). You can, at least, verify it's at least formatted like one
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
//Email is valid
}
You can add another check if you want. Parse the domain out and then run checkdnsrr
if(checkdnsrr($domain)) {
// Domain at least has an MX record, necessary to receive email
}
Many people get to this point and are still unconvinced there's not some hidden method out there. Here are some notes for you to consider if you're bound and determined to validate email:
-
Spammers also know the "connection trick" (where you start to send an email and rely on the server to bounce back at that point). One of the other answers links to this library which has this caveat
Some mail servers will silently reject the test message, to prevent spammers from checking against their users' emails and filter the valid emails, so this function might not work properly with all mail servers.
In other words, if there's an invalid address you might not get an invalid address response. In fact, virtually all mail servers come with an option to accept all incoming mail (here's how to do it with Postfix). The answer linking to the validation library neglects to mention that caveat.
Spam blacklists. They blacklist by IP address and if your server is constantly doing verification connections you run the risk of winding up on Spamhaus or another block list. If you get blacklisted, what good does it do you to validate the email address?
If it's really that important to verify an email address, the accepted way is to force the user to respond to an email. Send them a full email with a link they have to click to be verified. It's not spammy, and you're guaranteed that any responses have a valid address.
I have been searching for this same answer all morning and have pretty much found out that it's probably impossible to verify if every email address you ever need to check actually exists at the time you need to verify it. So as a work around, I kind of created a simple PHP
script to verify that the email address is formatted correct and it also verifies that the domain name used is correct as well.
GitHub
here https://github.com/DukeOfMarshall/PHP---JSON-Email-Verification/tree/master
<?php
# What to do if the class is being called directly and not being included in a script via PHP
# This allows the class/script to be called via other methods like JavaScript
if(basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])){
$return_array = array();
if($_GET['address_to_verify'] == '' || !isset($_GET['address_to_verify'])){
$return_array['error'] = 1;
$return_array['message'] = 'No email address was submitted for verification';
$return_array['domain_verified'] = 0;
$return_array['format_verified'] = 0;
}else{
$verify = new EmailVerify();
if($verify->verify_formatting($_GET['address_to_verify'])){
$return_array['format_verified'] = 1;
if($verify->verify_domain($_GET['address_to_verify'])){
$return_array['error'] = 0;
$return_array['domain_verified'] = 1;
$return_array['message'] = 'Formatting and domain have been verified';
}else{
$return_array['error'] = 1;
$return_array['domain_verified'] = 0;
$return_array['message'] = 'Formatting was verified, but verification of the domain has failed';
}
}else{
$return_array['error'] = 1;
$return_array['domain_verified'] = 0;
$return_array['format_verified'] = 0;
$return_array['message'] = 'Email was not formatted correctly';
}
}
echo json_encode($return_array);
exit();
}
class EmailVerify {
public function __construct(){
}
public function verify_domain($address_to_verify){
// an optional sender
$record = 'MX';
list($user, $domain) = explode('@', $address_to_verify);
return checkdnsrr($domain, $record);
}
public function verify_formatting($address_to_verify){
if(strstr($address_to_verify, "@") == FALSE){
return false;
}else{
list($user, $domain) = explode('@', $address_to_verify);
if(strstr($domain, '.') == FALSE){
return false;
}else{
return true;
}
}
}
}
?>