1 <?php 2 /** 3 * function getmxrr 4 * 获取指定域名的MX记录信息 5 */ 6 function win_getmxrr($hostname, &$mxhosts, &$mxweight=false) 7 { 8 if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') return; 9 if (!is_array ($mxhosts) ) $mxhosts = array(); 10 if (empty($hostname)) return; 11 $exec='nslookup -type=MX '.escapeshellarg($hostname); 12 @exec($exec, $output); 13 if (empty($output)) return; 14 $i=-1; 15 foreach ($output as $line) { 16 $i++; 17 if (preg_match("/^$hostname\tMX preference = ([0-9]+), mail exchanger = (.+)$/i", $line, $parts)) { 18 $mxweight[$i] = trim($parts[1]); 19 $mxhosts[$i] = trim($parts[2]); 20 } 21 if (preg_match('/responsible mail addr = (.+)$/i', $line, $parts)) { 22 $mxweight[$i] = $i; 23 $mxhosts[$i] = trim($parts[1]); 24 } 25 } 26 return ($i!=-1); 27 } 28 if (!function_exists('getmxrr')) { 29 function getmxrr($hostname, &$mxhosts, &$mxweight=false) { 30 return win_getmxrr($hostname, $mxhosts, $mxweight); 31 } 32 } 33 34 /** 35 * class EmailLinker 36 * 邮箱验证类,正则匹配邮箱地址并对域名是否有MX解析进行验证 37 */ 38 class EmailLinker 39 { 40 CONST CONN_TIMEOUT = 10; 41 CONST READ_TIMEOUT = 5; 42 CONST SMTP_PORT = 25; 43 private $email; 44 function __construct($email) 45 { 46 $this->email = $email; 47 $this->redirectIfNeeded(); 48 } 49 //重定向邮箱地址 50 function redirectIfNeeded() 51 { 52 if(array_key_exists('mail',$_GET) && $this->email == base64_decode($_GET['mail']) ){ 53 header('Location: mailto:'.$this->email); 54 exit; 55 } 56 } 57 58 //回调返回邮箱地址 59 public function link() 60 { 61 if($this->isValid()){ 62 $encoded = base64_encode($this->email); 63 return '<a href="?mail='.urlencode($encoded).'" target="_blank">Email:'.$this->email.'</a>'; 64 } 65 } 66 //获取邮箱地址并验证 67 public function isValid($mail = '') 68 { 69 static $valid = null; 70 if($mail){ 71 return ( $this->getParts() != null ); 72 } 73 if($valid !== null){ 74 return $valid; 75 } 76 if($parts = $this->getParts()){ 77 $valid = $this->validateUser($parts['host'],$parts['user']); 78 } 79 return $valid; 80 } 81 private function validateUser($hostname,$user) 82 { 83 if($sock = $this->openSMTPSocket($hostname)){ 84 $this->smtpSend($sock,"HELO $hostname"); 85 $resp = $this->smtpSend($sock,"MALL FROM: <$user@$hostname>"); 86 //$resp = $this->smtpSend($sock,"RCPT TO:<$user@$hostname>"); //这一步可能被ISP过滤了,导致邮箱验证不成功 87 $vaild = (preg_match('/250|451|452\s/',$resp) == 1); 88 fclose($sock); 89 return $vaild; 90 }else{ 91 return false; 92 } 93 } 94 private function openSMTPSocket($hostname) 95 { 96 $hosts = $this->getMX($hostname); 97 foreach($hosts as $host => $weight) 98 { 99 if($sock = @fsockopen($host,self::SMTP_PORT,$errno,$errstr,self::CONN_TIMEOUT)) 100 { 101 stream_set_timeout($sock,self::READ_TIMEOUT); 102 return $sock; 103 } 104 } 105 } 106 private function getMX($hostname) 107 { 108 $host = array(); 109 $weights = array(); 110 getmxrr($hostname,$hosts,$weights); 111 112 $results = array(); 113 foreach($hosts as $i => $host) 114 { 115 $results[$host] = $weights[$i]; 116 } 117 arsort($results,SORT_NUMERIC); 118 $results[$hostname] = 0; 119 return $results; 120 } 121 private function smtpSend($sock,$data) 122 { 123 fwrite($sock,"$data\r\n"); 124 return fgets($sock,1024); 125 } 126 127 //正则匹配 128 private function getParts() 129 { 130 //$emailRegex = '/\w+([-+.]\w+)*@\w+([-.]\w)*\.\w+([-.]\w+)*/x'; 131 $emailRegex = <<<__REGEX__ 132 /(?P<user> 133 \w+([-+.]\w+)* 134 )@(?P<host> 135 \w+([-.]\w)*\.\w+([-.]\w+)* 136 )/x 137 __REGEX__; 138 return (preg_match($emailRegex,$this->email,$matches))? $matches : null ; 139 } 140 141 } 142 $emailLinker_class = new EmailLinker('421865564@qq.com'); 143 echo $emailLinker_class->link(); 144 145 146 147 ?>
源代码下载:EmailLinker_1228.zip