• PHP 邮箱验证类 正则匹配并域名验证


      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

  • 相关阅读:
    [day002]剑指 Offer 09. 用两个栈实现队列
    [day003]718. 最长重复子数组
    [linux]关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    96. 不同的二叉搜索树
    91. 解码方法
    [动态规划]64. 最小路径和
    62.不同路径
    【Java】list根据某一条件进行分组
    【Java】批量生成小程序参数码并打包下载
    【Docker】使用docker制作libreoffice镜像并解决中文乱码问题
  • 原文地址:https://www.cnblogs.com/linzhenjie/p/2836643.html
Copyright © 2020-2023  润新知