php驗證郵件地址的有效性

SMTP和STMP命令 具體SMTP指令問題不做深究 有興趣者可參考http://www.magicwinmail.com/technic_smtp.php Smtp(Simple Mail Transfer  Protocol)協議是爲保證電子郵件的可靠和高效傳輸,TCP/IP協議的應用層中包含有SMTP協議,但是事實上其與傳輸系統和機制無關,只要一個 可靠的數據流通道,該協議可以工作在TCP上,也可以工作在NCP,NITS等協議上,在TCP上,其使用端口25進行傳輸。STMP的重要特點是可以交 互的通信系統中傳發郵件。     SMTP提供了一種郵件傳輸的機制,當接受方和發送方都種子 一  個網絡上時,可以把郵件直接傳給對方,當雙方不在同一網絡上時,需要通過一個或幾個中間服務器轉發。STMP首先由發送方提供聲請,要求與控接方SMTP 建立雙向通道,接收方可以是最後接件人也可以是中間轉發的服務器,接收服務器確認可以建立連接後,雙發就可以開始通信。     發送方SMTP向接受方發出Mail命令,告知發送方的身份,如果回答OK。發送方再發出RCPT命令,告知收件人的身份,接收方SMTP確認是否接收或轉發,如果同意就回答OK,接下來幾可以進程數據傳輸拉。     那SMTP 的命令是什麼拉?STMP中定義15個命令,其中SMTP工作的基本的命令有7個,HELO,MAILFROM,RCPT TO,DATA,REST,NOOP和QUIT; 下面我們介紹一下這幾個命令:     HELO:發送方問候接收方,後面是發件人的服務器地址或標誌;     MAILFROM:開始發送郵件,起後面跟隨發送郵件發送方 的地址;     RCPT TO:接受方收件人的郵箱     DATA:接收方把把該命令之後的數據作爲發送數據;     REST:接收方復位;     NOOP:這個命令不影響任何參數,只是要求接收回答OK,不會影響緩衝區的數據;     OUIT;SMTP要求接受方需要回答OK;然後中斷傳輸在接到這個命令並回答OK前,接受方不得中斷連接,即使傳輸出現錯誤。  setEmails($emails);           }           if ($sender) {                $this->setSenderEmail($sender);           }       }      //解析郵箱地址       function _parseEmail($email)       {           $parts = explode('@', $email);           $domain = array_pop($parts);           $user= implode('@', $parts);           return array($user, $domain);       }             /**        * 設置受事郵件地址        * @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[0];//郵箱地址           $this->from_domain = $parts[1];//郵箱域名       }             /**       * 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)) {               // 用fsockopen鏈接受事地址STMP服務器                                $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('/^([0-9]{3}) /ims', $reply,$matches);               $code = isset($matches[1]) ? $matches[1] : '';                          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('/^([0-9]{3}) /ims', $reply,$matches);                    $code = isset($matches[1]) ? $matches[1] : '';                                   if ($code == '250') {                    // you received 250 so the email address was accepted 250表示已收信                         $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("END\n$msg\n");           $this->debug("START\n$reply");                  return $reply;      }             /**        * Query DNS server for MX entries  getmxrr()函數取得指定網址 DNS 記錄之 MX 字段。        * @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 '
'.htmlentities($str).'
';           }      } } 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 = '[email protected]'; // an optional sender $sender = '[email protected]'; // 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';       }   } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章