3

给定一个电子邮件地址,我如何验证它是否有效?(该电子邮件的域将接受该地址的电子邮件。)

这在 PHP 中看起来如何?

注意:我不想验证电子邮件地址本身在语法上是否有效。我想知道该域是否会接受发送到该地址的电子邮件。

我本以为有某种方法可以使用 MX 记录或其他东西来做到这一点......

4

7 回答 7

4

我认为您唯一的选择是 SMTP RCPT TO 或 VRFY 命令。

RCPT TO可能是一种检查方式,只要您在发出后断开连接即可。但是,如果帐户不存在,并非所有服务器都会启动您(uce 预防、捕获所有地址等)。

VRFY 可以告诉您该服务器上是否存在帐户,但这几乎总是被禁用以防止帐户探测。

执行 RCPT TO 验证(以及其他方法)的 PHP 类是:http ://code.google.com/p/php-smtp-email-validation/

于 2010-05-15T04:33:18.320 回答
2

既然你特别说明

该电子邮件的域将接受该地址的电子邮件。

没有正则表达式可以帮助你。验证这一点的唯一方法是尝试向该地址发送一封电子邮件,看看它是否被退回。即使这样,您也可能会收到误报,因为邮件服务器可能不会发送失败通知。

使用 PHP 发送这样的基本电子邮件相当简单;在此处查看该mail()功能的文档。

于 2010-05-15T03:47:13.530 回答
1

您实际上无法检查服务器是否会接受它。邮件服务器没有 API 来处理它。

曾经有一个脚本试图连接到 MX 服务器,并从服务器中寻找某种表明它需要密码的响应,而不是仅仅将其作为未使用的邮箱拒绝。然而,这是非常糟糕的做法。

您几乎可以做的唯一一件事就是检查有效的电子邮件地址,并希望最好:

http://www.linuxjournal.com/article/9585

这是实际上遵循 RFC 标准的教程之一。

/**
Validate an email address.
Provide email address (raw input)
Returns true if the email address has the email 
address format and the domain exists.
*/
function validEmail($email)
{
   $isValid = true;
   $atIndex = strrpos($email, "@");
   if (is_bool($atIndex) && !$atIndex)
   {
      $isValid = false;
   }
   else
   {
      $domain = substr($email, $atIndex+1);
      $local = substr($email, 0, $atIndex);
      $localLen = strlen($local);
      $domainLen = strlen($domain);
      if ($localLen < 1 || $localLen > 64)
      {
         // local part length exceeded
         $isValid = false;
      }
      else if ($domainLen < 1 || $domainLen > 255)
      {
         // domain part length exceeded
         $isValid = false;
      }
      else if ($local[0] == '.' || $local[$localLen-1] == '.')
      {
         // local part starts or ends with '.'
         $isValid = false;
      }
      else if (preg_match('/\\.\\./', $local))
      {
         // local part has two consecutive dots
         $isValid = false;
      }
      else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
      {
         // character not valid in domain part
         $isValid = false;
      }
      else if (preg_match('/\\.\\./', $domain))
      {
         // domain part has two consecutive dots
         $isValid = false;
      }
      else if
(!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/',
                 str_replace("\\\\","",$local)))
      {
         // character not valid in local part unless 
         // local part is quoted
         if (!preg_match('/^"(\\\\"|[^"])+"$/',
             str_replace("\\\\","",$local)))
         {
            $isValid = false;
         }
      }
      if ($isValid && !(checkdnsrr($domain,"MX") || 
 ↪checkdnsrr($domain,"A")))
      {
         // domain not found in DNS
         $isValid = false;
      }
   }
   return $isValid;
}

在确保能够发送电子邮件的方式中,验证与您将获得的一样好。

于 2010-05-15T03:45:34.437 回答
1

验证电子邮件地址是否有效有多容易?

一点都不容易。看看Dominic Sayers 的PHP 电子邮件验证,它可能是任何语言中最完整的电子邮件验证库。它还包括 DNS 检查。

另请参阅Jeff Atwood 的这篇相关文章,了解确保电子邮件到达所需的检查。

于 2010-05-15T03:53:51.093 回答
0

电子邮件(在语法上)有效与它接受电子邮件不同。为了检查域是否会接受电子邮件,您必须尝试直接向 MX 发送电子邮件,但即使这样,如果被 SMTP 服务器接受,您也不能保证以后不会被拒绝,即将发送未送达报告。如果您在动态地址池中或没有 DNS 反向,SMTP 服务器可能会拒绝您的电子邮件

于 2010-05-15T03:50:01.090 回答
0

只是想我会提到 PHP 有一个内置函数getmxrr(),可以从域中检索 MX 记录。

这有什么用,我不知道......在页面上它指出:

此功能不应用于地址验证。

所以它的用途仅限于验证一个域甚至有一个邮件服务器。

于 2010-05-15T04:10:36.703 回答
-1

如果您使用的是 PHP 5.2.x,现在不需要使用自定义验证函数。PHP带有一个内置函数

于 2010-05-15T03:55:20.387 回答