敷衍一下,今天找到了前两年写的一个邮箱验证的类,验证邮箱是否存在。下边直接放代码:



/**
 * 验证邮箱是否存在的类
 * 
 * @github https://gist.github.com/widuu/7828e70ce6ee5f087798dd0dc18100dc
 * @author widuu 
 */
 
namespace framework\system;

class verifyEmail{
	
	/**
	 * 连接超时时间
	 */
	
	CONST CONN_TIMEOUT = 10;
	
	/**
	 * 读取超时时间
	 */
	 
	CONST READ_TIMEOUT = 5;
	
	/**
	 * 打开端口
	 */
	
	CONST SMTP_PORT = 25;
	
	private function __construct(){}
	
	/**
	 * 验证邮箱方法
	 *
	 * @param   $email string 要验证的邮箱
	 * @return  array  status = [0=>'不存在',1=>'存在'] errMsg=>错误信息|查询信息
	 */
	 
	static public function verify($email = '')
	{
		if( empty($email) ){
			return ['status'=>0,'errMsg'=>'邮箱不能为空'];
		}
		
		// 验证邮箱地址是否错误
		$email_info = self::getEmailInfo($email);
		if( is_null($email_info) ){
			return ['status'=>0,'errMsg'=>'邮箱地址错误'];
		}
		
		// 验证DNS是否存在
		$mx_info = self::verifyMax($email_info['host']);
		if( !$mx_info ){
			return ['status'=>0,'errMsg'=>'DNS 解析不存在'];
		}

		// 验证用户是否存在
		$result = self::verifyUser($email_info, $mx_info['data']);
		if( $result['status'] ){
			return ['status'=>1, 'errMsg'=>$result['msg'] ];
		}else{
			return ['status'=>0, 'errMsg'=>$result['msg'] ];
		}
		
	}
	
	/**
	 * 验证邮箱是否存在
	 *
	 * @author widuu 
	 */
	 
	private static function verifyUser( $email_info = [] ,$host_array = [] )
	{
		$sock = null;
		$hostname = '';
		foreach($host_array as $weight => $host)
		{
			if($sock = @fsockopen($host,self::SMTP_PORT,$errno,$errstr,self::CONN_TIMEOUT))
			{
				$hostname = $host;
				stream_set_timeout($sock,self::READ_TIMEOUT);
				break;
			}
		}
		if( !$sock ){
			return false;
		}
		$resp[0] = "Connection succeeded to {$hostname} SMTP.";
		$resp[1] = fgets($sock,1024);
		$resp[2] = "HELO baidu.com";
		fputs($sock, "HELO baidu.com\r\n");
		$resp[3] = fgets($sock,1024);
		$resp[4] = "MAIL FROM:";
		fputs($sock, "MAIL FROM:\r\n");
		$resp[5] = fgets($sock,1024);
		$resp[6] = "RCPT TO:<".$email_info['user']."@".$email_info['host'].">";
		fputs($sock, "RCPT TO:<".$email_info['user']."@".$email_info['host'].">\r\n");
		$resp[7] = fgets($sock,1024);
		$vaild = (preg_match('/250|451|452\s/',$resp[7]) == 1);
		fclose($sock);
		return ['status'=>$vaild, 'msg'=>$resp];
	}
	
	/**
	 * 验证邮箱的MAX记录
	 *
	 * @author widuu 
	 */
	 
	private static function verifyMax($hostname = '')
	{
		$mxhosts = array();
		$weight  = array();
		$result  = getmxrr($hostname, $mxhosts, $weight);
		if( !$result ){
			return false;
		}
		$mx_array = array_combine($weight, $mxhosts);
		arsort($mx_array,SORT_NUMERIC);
		$return_info = [ 'hostname'=>$mxhosts[0], 'data'=>$mx_array ];
		return $return_info;
	}
	
	/**
	 * 正则表达式验证是否是邮箱
	 *
	 * @author widuu 
	 */
	 
	private static function getEmailInfo($email)
	{
		$emailRegex = <<<__REGEX__
		/(?P
			\w+([-+.]\w+)*
		 )@(?P
		 	\w+([-.]\w)*\.\w+([-.]\w+)*
		 )/x
__REGEX__;
		return (preg_match($emailRegex,$email,$matches))? $matches : null ;
	}
}

var_dump(verifyEmail::verify('widuu@baidu.com'));

返回内容如下:

array(2) {
  ["status"]=>
  int(0)
  ["errMsg"]=>
  array(8) {
    [0]=>
    string(49) "Connection succeeded to mx.maillb.baidu.com SMTP."
    [1]=>
    bool(false)
    [2]=>
    string(14) "HELO baidu.com"
    [3]=>
    bool(false)
    [4]=>
    string(28) "MAIL FROM:"
    [5]=>
    bool(false)
    [6]=>
    string(25) "RCPT TO:"
    [7]=>
    bool(false)
  }
}

当初写这个是因为做一个异步任务队列,群发邮件和短信,都知道邮件地址错误多了就被封了,所以当初做了这个,整套系统前期是workman,后期swoole,因为前期是windows服务器。现在放出来。

点赞(31) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部