Quick (and a bit dirty) PHP email address list validator

If your host system is full of bad/spammy email addresses, the following very quick and dirty PHP code might help you identify the duds. It takes as input a flat file full of email addresses, and uses nslookup (on Mac and Win) to check a response from the email addresses domain. The bad email addresses are written to a file you nominate.
It's quick and it's dirty because looking up a server to confirm an email address is a simple, but very imperfect way of validating the email addresses. A more sophisticated is to query the mail server itself on port 25, but that might be overkill when you've got 1000s of addresses to check.

This script might be useful to people setting up the CM account and importing lists that might have dodgy data in them. FYI I ran it on a previously un-vetted email subscription table and came up with 25% dud addresses! Most of them were looking for a notes area to stick words like 'viagra' and 'vicodin' in them!

Any improvements/comments/criticisms most welcome!



 * Read a file of email addresses, and write out the dud ones to a new file.
 * Uses a well-formed check, and a simple domain check via 
 * nslookup.
 * command used is: nslookup -q=mx bigpond.com

// Set up here:
// 1. What is the string in nslookup response that tells you the server exists?
$serverFoundString = 'mail exchanger';
// 2. What's the input file of email addresses called?
$emailInFile = 'maillist_test.csv';
// 3. What's the output file of invalid email addresses called?
$dudEmailOutFile = 'dudemail_test.csv';
// 4. What delimiter file are you using (in and out)?
$emailFileDelim = "\t";

// What column is the email address in (starting at 0)?
// Name in col 0+1, Email address in column 2
$emailAddressCol = 2;

$rec = 0;
$badFormRec = 0;
$noServerRec = 0;
// Write dud emails to this file.
// Open up the email file.
if (($emailFileHandle = fopen($emailInFile, "r")) !== FALSE) {
// Process it, tab delimited.
    while (($data = fgetcsv($emailFileHandle, 1000, $emailFileDelim)) !== FALSE) {
    // Is it well-formed?
    if (EmailFormCheck($data[$emailAddressCol])) {
        // Yes well-formed, now, does the server exist?
        if (checkEmail($data[$emailAddressCol]) == false) {
        $data[]="Server not found";
        echo "NO SERVER\t" . $data[2] . "<br />";
        else {
        // Record ok
        echo "EMAIL OK\t" . $data [2] . "<br />";
    else {
        $data[]="Email address not well-formed";
        fputcsv($outputFile,$data, $emailFileDelim);
        echo "BAD FORM\t" . $data[2] . "<br />";
    // For testing purposes, may want a limit here.
    if ($rec>=10000) {
        fclose($emailFileHandle) ;
    echo "FINISHED CHECKING: " . $rec . " RECORDS<br/>. There were " .
    $badFormRec . 
    " records not well-formed and " . $noServerRec . 
    " records where nslookup could not find the domain name.";

// Bye bye

 * Check an email address to see if its domain name exists out there.
 * A quick-and-dirty check of email addresses. Better checking would query 
 * the mail server on port 25 etc... This way is much simpler, BUT NOT PERFECT.
 * @param type $email The email address to check
 * @return bool True = domain name (server) of email address found. False = 
 *                     nslookup could not find the server.
function checkEmail($email) {
    global $serverFoundString;    
    // Chop the email address up
    // The server name is in element 1 ie. $email_parts[1]
    $email_parts = split('@',$email); 
    $resp = array();
    // Run nslookup, $resp will contain an array of strings as response.
    echo exec('nslookup -q=mx ' . $email_parts[1],$resp);
    // Here's out test. Not infallible, but seems to do the job.
    // Search for words 'mail exchanger' in response from nslookup
    // If there, it means server was found.
    // Run nslookup -q=mx your@emailaddress.com in a terminal session to 
    // see what your system returns, and modify this search string if need be.
    $needle = $serverFoundString;
    // Check response to see if any element contains the text.
    if (my_inArray($needle, $resp)) {
    return true;
    else return false;


 * Search an array to see if any text contains the search argument.
 * @param string $needle
 * @param array $haystack
 * @return bool True = string found, false = not found 
function my_inArray($needle, $aryHaystack) {
    // For each array element, search the element string.
    foreach ($aryHaystack as $value) {
    // Case-insensitive search of string, returns the position
    // in the string where the search argument is found.
    // Returns FALSE if not found (===)
    if (stripos($value,$needle)) {
        // Found
        return true;
    // Nope, the searchs string was not found in any element.
    return false;

 * Check an email address format for validity using regex only.
 * @param type $email
 * @return bool True = email address well-formed, false = not well-formed.
function EmailFormCheck($email) {
return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $email);


See why 200,000 companies worldwide love Campaign Monitor.

From Australia to Zimbabwe, and everywhere in between, companies count on Campaign Monitor for email campaigns that boost the bottom line.

Get started for free