如何来检测一个 email 地址?一般就需要从邮件地址的 smtp 服务器来获取一些信息来判断。
假设我要检测 testmail@douban.com 这个地址是不是真存在:
然后根据得到的 MX 地址来检测,用 telnet MX记录 端口号
来连接,然后输入命令:
从结果中基本可以看到 testmail@douban.com 这个地址返回的是 250 状态,是存在的;而下面的 jfksdjglfdgld@douban.com 则返回了 550 状态,同时也可以从下面的描述语句中得到这个地址则是不存在的。
下在的类就是根据上面的脚本写的一个 php 类,用来检测邮件地址是否真实存在。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* 检测一个邮件地址是否真实存在 | |
*/ | |
class verify_email { | |
public $debug = FALSE; | |
public $time_out = 30; | |
public $host_name = 'localhost'; | |
public $smtp_port = 25; | |
public $log_str = ""; | |
public $from = ''; | |
public $sock; | |
public function __construct($from = "", $smtp_port = 25) { | |
$this->smtp_port = $smtp_port; | |
$this->from = $from; | |
$this->time_out = 30; //is used in fsockopen() | |
$this->sock = FALSE; | |
} | |
public function check_mail($address) { | |
$this->log_write("BEGINING CHECK address: ". $address . "\n"); | |
if(!$this->is_email($address)) { | |
$this->log_write("not an email address.\n"); | |
return FALSE; | |
} | |
// | |
if (TRUE !== $this->smtp_sockopen($address)) { | |
return FALSE; | |
} | |
if (!$this->smtp_putcmd("HELO", $this->host_name)) { | |
$this->log_write("sending HELO command\n"); | |
return FALSE; | |
} | |
if (!$this->smtp_putcmd("MAIL", "FROM:<" . $this->from . ">")) { | |
$this->log_write("sending MAIL FROM command\n"); | |
return FALSE; | |
} | |
if (!$this->smtp_putcmd("RCPT", "TO:<" . $address . ">")) { | |
$this->log_write("sending MAIL TO command\n"); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
private function is_email($address) { | |
return preg_match("/^[0-9a-zA-Z]+@(([0-9a-zA-Z]+)[.])+[a-z]{2,4}$/i",$address); | |
} | |
private function smtp_sockopen($address) { | |
return $this->smtp_sockopen_mx($address); | |
} | |
private function smtp_sockopen_mx($address) { | |
$domain = preg_replace("/^.+@([^@]+)$/i", "$1", $address); | |
if (!@getmxrr($domain, $MXHOSTS)) { | |
$this->log_write("Error: Cannot resolve MX \"" . $domain . "\"\n"); | |
return FALSE; | |
} | |
foreach ($MXHOSTS as $host) { | |
$this->log_write("Trying to " . $host . ":" . $this->smtp_port . "\n"); | |
$this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out); | |
if (!($this->sock && $this->smtp_ok())) { | |
$this->log_write("Warning: Cannot connect to mx host " . $host . "\n"); | |
$this->log_write("Error: " . $errstr . " (" . $errno . ")\n"); | |
continue; | |
} | |
$this->log_write("Connected to mx host " . $host . "\n"); | |
return TRUE; | |
} | |
$this->log_write("Error: Cannot connect to any mx hosts (" . implode(", ", $MXHOSTS) . ")\n"); | |
return FALSE; | |
} | |
private function smtp_putcmd($cmd, $arg = "") { | |
if ($arg != "") { | |
if ($cmd == "") | |
$cmd = $arg; | |
else | |
$cmd = $cmd . " " . $arg; | |
} | |
fputs($this->sock, $cmd . "\r\n"); | |
$this->smtp_debug("> " . $cmd . "\n"); | |
return $this->smtp_ok(); | |
} | |
private function smtp_ok() { | |
$response = str_replace("\r\n", "", fgets($this->sock, 512)); | |
$this->smtp_debug($response . "\n\n"); | |
if (!ereg("^[23]", $response)) { | |
fputs($this->sock, "QUIT\r\n"); | |
fgets($this->sock, 512); | |
$this->log_write("Error: Remote host returned \"" . $response . "\"\n"); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
private function log_write($str) { | |
$this->log_str .= $str; | |
} | |
public function get_log() { | |
$str = $this->log_str; | |
$this->log_str = ''; | |
return $str; | |
} | |
private function smtp_debug($message) { | |
if ($this->debug) { | |
echo $message; | |
} | |
} | |
} | |
// Testing | |
$newemail = "doubanjgdl@kfdkldfg@163.com"; | |
$randval = substr(md5(uniqid(rand())), 0, 6); | |
$verifyEmail = new verify_email($randval . "@mailtest.com"); | |
echo $newemail . ' is '; | |
if (TRUE === $verifyEmail->check_mail($newemail)) { | |
echo "OK\n"; | |
} else { | |
echo "BAD\n"; | |
} | |
//echo $verifyEmail->get_log(); |