i tend to use this, although its not foolproof, and id still use some variety of email confirmation....
function validateEmail($email){
global $SERVER_NAME;
$return = array ( false, "", "", "" );
list ( $user, $domain ) = split ( "@", strtolower($email), 2 );
$arr = explode ( ".", $domain );
// Quickie shortcut - if the domain as a whole is OK or it has MX, then just return with true and hope for the best
if (gethostbyname($domain) != $domain || checkdnsrr ( $domain, "MX" )) {
$return[0] = true;
return $return;
};
// figure out how many parts to the host/domain name portion there are
$count = count($arr);
// get our Top-Level Domain portion (i.e. foobar.org)
$tld = $arr[$count - 2] . "." . $arr[$count - 1];
// Some tld's have two parts - find them and split them out
$lastun = $arr[$count - 1];
if ($lastun != "com" && $lastun != "net" && $lastun != "org") {
$tld = $arr[$count - 3] . "." . $arr[$count - 2] . "." . $arr[$count - 1];
};
// check that an MX record exists for Top-Level Domain, and if so start our email address checking
if (checkdnsrr($tld,"MX")) {
// Okay...valid dns reverse record; test that MX record for host exists, and then fill the 'mxhosts' and 'weight'
// arrays with the correct information
if (getmxrr($tld,$mxhosts,$weight)){
// sift through the 'mxhosts' connecting to each host
for ($i = 0;$i < count($mxhosts);$i++) {
// open socket on port 25 to mxhosts, setting returned file pointer to the variable 'fp'
$fp = fsockopen($mxhosts[$i],25);
// if the 'fp' was set, then goto work
if ($fp) {
// work variables
$s = 0;
$c = 0;
$out = "";
// set our created socket for 'fp' to non-blocking mode so our fgets() calls will return right away
set_socket_blocking ($fp,false);
// as long as our 'out' variable has a null value ("") keep looping (do) until we get something
do {
// output of the stream assigned to 'out' variable
$out = fgets($fp,2500);
// if we get an "220" code (service ready code (i.e greeting))
// increment our work (code (c)) variable, and null
// out our output variable for a later loop test
if (ereg("^220",$out)) {
$s = 0;
$out = "";
$c++;
$return[2] = true;
$return[3] = $mxhosts[$i];
// elseif c is greater than 0
// and 'out' is null (""),
// we got a code back from some
// server, and we've passed
// through this loop at least
// once
} elseif (($c > 0) && ($out == "")){
$return[2] = true;
break;
// else increment our 's'
// counter
} else {
$s++;
}
// and if 's' is 9999, break, to
// keep from looping
// infinetly
if ( $s == 9999 ) {
break;
}
} while ($out == "");
// reset our file pointer to blocking
// mode, so we wait
// for communication to finish before
// moving on...
set_socket_blocking ( $fp, true );
// talk to the MX mail server, validating ourself (HELO)
fputs ( $fp, "HELO $SERVER_NAME\n" );
// get the mail servers reply, assign to 'output' (ignored)
$output = fgets($fp,2000);
// give a bogus "MAIL FROM:" header to the server
fputs($fp,"MAIL FROM: <info@".$tld.">\n");
// get output again (ignored)
$output = fgets($fp,2000);
// give RCPT TO: header for the email address we are testing
fputs ( $fp, "RCPT TO: <$email>\n" );
// get final output for validity testing (used)
$output = fgets ( $fp, 2000 );
// test the reply code from the mail server for the 250 (okay) code
if (ereg("^250",$output)) {
// set our true/false(ness)
// array item for testing
$return[0] = true;
} else {
// otherwise, bogus address, fillin the 2nd array item with the mail servers reply
// code for user to test if they want
$return[0] = false;
$return[1] = $output;
}
// tell the mail server we are done talking to it
fputs($fp,"QUIT\n");
// close the file pointer
fclose($fp);
// if we got a good value break, otherwise, we'll keep trying MX records until we get a good
// value, or we exhaust our possible MX servers
if ($return[0] == true){
break;
}
}
}
}
} else {
// No MX record appears for the specified Top-Level Domain; possibly
// an invalid host/domain name was specified.
$return[0] = false;
$return[1] = "Invalid email address (bad domain name)";
$return[2] = false;
}
// end if checkdnsrr() return the array for the user to test against
return $return;
};