err23211 发表于 2015-1-29 08:56:33

php验证邮件地址的有效性

<?php
/**
* Validate Email Addresses Via SMTP
* This queries the SMTP server to see if the email address isaccepted.
* @author 臭三八
* @version 1.0
*/
class SMTP_validateEmail {
      /**
       * PHP Socket resource to remote MTA
       * @var resource $sock
       */
      var $sock;
      
      /**
       * Current User being validated
       */
      var $user;
      /**
       * Current domain where user is being validated
       */
      var $domain;
      /**
       * List of domains to validate users on
       */
      var $domains;
      /**
       * SMTP Port
       */
      var $port = 25;
      /**
       * Maximum Connection Time to wait for connectionestablishment per MTA
       */
      var $max_conn_time = 30;
      /**
       * Maximum time to read from socket before giving up
       */
      var $max_read_time = 5;
      
      /**
       * username of sender
       */
      var $from_user = 'user';
      /**
       * Host Name of sender
       */
      var $from_domain = 'localhost';
      
      /**
       * Nameservers to use when make DNS query for MX entries
       * @var Array $nameservers
       */
      var $nameservers = array(
          '192.168.0.1'
      );
      
      var $debug = false;
      
      /**
       * Initializes the Class
       * @return SMTP_validateEmail Instance
       * @param $email Array List of Emails toValidate
       * @param $sender String Email of validator
       */
      function SMTP_validateEmail($emails = false, $sender =false)
      {
          if ($emails) {
               $this->setEmails($emails);
          }
          if ($sender) {
               $this->setSenderEmail($sender);
          }
      }
      
      function _parseEmail($email)
      {
          $parts = explode('@', $email);
          $domain = array_pop($parts);
          $user= implode('@', $parts);
          return array($user, $domain);
      }
      
      /**
       * Set the Emails to validate
       * @param $emails Array List of Emails
       */
      function setEmails($emails)
      {
          foreach ($emails as $email) {
            list($user, $domain) = $this->_parseEmail($email);
            if (!isset($this->domains[$domain])) {
                  $this->domains[$domain] = array();
            }
            $this->domains[$domain][] = $user;
          }
      }
      
      /**
       * Set the Email of the sender/validator
       * @param $email String
       */
      function setSenderEmail($email)
      {
          $parts = $this->_parseEmail($email);
          $this->from_user = $parts;
          $this->from_domain = $parts;
      }
      
      /**
      * Validate Email Addresses
      * @param String $emails Emails to validate (recipientemails)
      * @param String $sender Sender's Email
      * @return Array Associative List of Emails and theirvalidation results
      */
      function validate($emails = false, $sender = false)
      {
         
          $results = array();
      
          if ($emails) {
               $this->setEmails($emails);
          }
          if ($sender) {
               $this->setSenderEmail($sender);
          }
      
          // query the MTAs on each Domain
          foreach($this->domains as $domain=>$users) {
      
          $mxs = array();
      
          // current domain being queried
          $this->domain = $domain;
      
          // retrieve SMTP Server via MX query on domain
          list($hosts, $mxweights) = $this->queryMX($domain);
      
          // retrieve MX priorities
          for($n = 0; $n < count($hosts); $n++){
            $mxs[$hosts[$n]] = $mxweights[$n];
          }
          asort($mxs);
      
          // last fallback is the original domain
          $mxs[$this->domain] = 0;
      
          $this->debug(print_r($mxs, 1));
      
          $timeout = $this->max_conn_time;
      
          // try each host
          while(list($host) = each($mxs)) {
            // connect to SMTP server
            $this->debug("try $host:$this->port\n");
            if ($this->sock = fsockopen($host, $this->port, $errno, $errstr, (float) $timeout)) {
                  stream_set_timeout($this->sock, $this->max_read_time);
                   break;
            }
          }
      
          //did we get a TCP socket
          if ($this->sock) {
            $reply = fread($this->sock, 2082);
            $this->debug("<<<\n$reply");
            
            preg_match('/^({3}) /ims', $reply,$matches);
            $code = isset($matches) ? $matches : '';
         
            if($code != '220') {
                  // MTA gave an error...
                  foreach($users as $user) {
                   $results[$user.'@'.$domain] = false;
                   }
                   continue;
            }
               
            // say helo
            $this->send("HELO ".$this->from_domain);
            // tell of sender
            $this->send("MAIL FROM: <".$this->from_user.'@'.$this->from_domain.">");
            
            // ask for each recepient on this domain
            foreach($users as $user) {
            
                   // ask of recepient
                   $reply = $this->send("RCPT TO: <".$user.'@'.$domain.">");
               
                  // get code and msg from response
                   preg_match('/^({3}) /ims', $reply,$matches);
                   $code = isset($matches) ? $matches : '';
               
                   if ($code == '250') {
                   // you received 250 so the email address was accepted
                        $results[$user.'@'.$domain] =true;
                   }
                   elseif ($code == '451' || $code == '452') {
                        // you received 451 so the email address was greylisted (or some temporary error occured on the MTA) - so assume is ok
                        $results[$user.'@'.$domain] =true;
                   }
                   else {
                        $results[$user.'@'.$domain] =false;
                   }
            
             }
            
            // reset before quit
            $this->send("RSET");
            
            // quit
            $this->send("quit");
            // close socket
            fclose($this->sock);
            }
          }
          return $results;
      }
      
      
   function send($msg) {
          fwrite($this->sock, $msg."\r\n");
      
          $reply = fread($this->sock, 2082);
      
          $this->debug(">>>\n$msg\n");
          $this->debug("<<<\n$reply");
      
          return $reply;
   }
      
      /**
       * Query DNS server for MX entries
       * @return
       */
   function queryMX($domain) {
          $hosts = array();
          $mxweights = array();
          if (function_exists('getmxrr')) {
          getmxrr($domain, $hosts, $mxweights);
   }
   else {
          // windows, we need Net_DNS
          require_once 'Net/DNS.php';
      
          $resolver = new Net_DNS_Resolver();
          $resolver->debug = $this->debug;
          // nameservers to query
          $resolver->nameservers = $this->nameservers;
          $resp = $resolver->query($domain, 'MX');
            if ($resp) {
                   foreach($resp->answer as $answer) {
                        $hosts[] = $answer->exchange;
                        $mxweights[] = $answer->preference;
                   }
            }
               
          }
          return array($hosts, $mxweights);
      }
      
      /**
       * Simple function to replicate PHP 5 behaviour.http://php.net/microtime
       */
   function microtime_float()
   {
       list($usec, $sec) = explode(" ", microtime());
       return ((float)$usec + (float)$sec);
   }
      
   function debug($str)
   {
          if ($this->debug) {
            echo '<pre>'.htmlentities($str).'</pre>';
          }
   }
}
set_time_limit(0);

//清空并关闭输出缓存
ob_end_clean();
flush(); //将输出发送给客户端浏览器
$mail_list = "add.txt";
$fp = fopen($mail_list,'r');
while(!feof($fp)){
$list[] = trim(fgets($fp));
}


//$email = '395582979@qq.com';
// an optional sender

$sender = 'gaocz@im.ac.cn';
// instantiate the class

$SMTP_Validator = new SMTP_validateEmail();
// turn on debugging if you want to view the SMTP transaction

$SMTP_Validator->debug = true;
// do the validation

foreach($list as $k=>$who){
if($who != ''){
      $results = $SMTP_Validator->validate(array($who),$sender);
      // view results
      //echo 'ok';
      echo $who.' 是'.($results[$who] ? '有效的' :'无效的')."\n";
      if($results[$who]){
      file_put_contents('result.txt',$who. "\r\n", FILE_APPEND);
      }
      // send email?

      if ($results[$who]) {
      //mail($email, 'Confirm Email', 'Please reply to this email to confirm', 'From:'.$sender."\r\n"); // send email

      }
      else {
      //file_put_contents('result.txt',$who. "\r\n", FILE_APPEND);
      //echo 'The email addresses you entered is not valid';
      }
}
}


页: [1]
查看完整版本: php验证邮件地址的有效性