php - 如何在不发送电子邮件的情况下检查电子邮件地址是否存在?

我发现这个PHP代码使用SMTP检查电子邮件地址而不发送电子邮件。

有没有人尝试过类似的东西或者它对你有用吗? 你能说出一个电子邮件客户/用户输入是否正确&存在?

php-guy asked 2019-07-12T16:14:00Z
13个解决方案
84 votes

您有时可以使用两种方法来确定收件人是否确实存在:

  1. 您可以连接到服务器,并发出VRFY命令。 很少有服务器支持此命令,但它仅用于此目的。 如果服务器以2.0.0 DSN响应,则用户存在。

    VRFY用户

  2. 您可以发出RCPT,并查看邮件是否被拒绝。

    邮件来自:<>

    RCPT TO:< user @ domain>

如果用户不存在,您将获得5.1.1 DSN。 但是,仅仅因为电子邮件未被拒绝,并不意味着用户存在。 某些服务器将默默地丢弃此类请求,以防止枚举其用户。 其他服务器无法验证用户,并且必须接受该消息。

还有一种称为灰名单的反垃圾邮件技术,它会导致服务器最初拒绝该地址,期望真正的SMTP服务器稍后会尝试重新传递。 这将破坏验证地址的尝试。

老实说,如果您尝试验证地址,最好的方法是使用简单的正则表达式来阻止显然无效的地址,然后发送一个带有链接的实际电子邮件回到您的系统,该链接将验证收到的电子邮件。 这也确保了用户输入了他们的实际电子邮件,而不是恰好属于其他人的轻微拼写错误。

Joseph Tary answered 2019-07-12T16:15:19Z
45 votes

这里的其他答案讨论了尝试这样做的各种问题。 我想我会告诉你如何尝试这个,以防你想通过自己学习来学习。

您可以通过telnet连接到邮件服务器,询问是否存在电子邮件地址。 以下是测试fsockopen的电子邮件地址的示例:

C:\>nslookup -q=mx stackoverflow.com
Non-authoritative answer:
stackoverflow.com       MX preference = 40, mail exchanger = STACKOVERFLOW.COM.S9B2.PSMTP.com
stackoverflow.com       MX preference = 10, mail exchanger = STACKOVERFLOW.COM.S9A1.PSMTP.com
stackoverflow.com       MX preference = 20, mail exchanger = STACKOVERFLOW.COM.S9A2.PSMTP.com
stackoverflow.com       MX preference = 30, mail exchanger = STACKOVERFLOW.COM.S9B1.PSMTP.com

C:\>telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
220 Postini ESMTP 213 y6_35_0c4 ready.  CA Business and Professions Code Section 17538.45 forbids use of this system for unsolicited electronic mail advertisements.

helo hi
250 Postini says hello back

mail from: <me@myhost.com>
250 Ok

rcpt to: <fake@stackoverflow.com>
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 w41si3198459wfd.71

带有数字代码的行是来自SMTP服务器的响应。 我添加了一些空行以使其更具可读性。

许多邮件服务器不会返回此信息作为防止垃圾邮件发送者收集电子邮件地址的方法,因此您不能依赖此技术。 但是,通过检测无效的邮件服务器或者如上所述拒绝收件人地址,您可能会成功清除一些明显不良的电子邮件地址。

另请注意,如果您对它们发出太多请求,邮件服务器可能会将您列入黑名单。


在PHP中我相信你可以使用fsockopen,fwritefread以编程方式执行上述步骤:

$smtp_server = fsockopen("STACKOVERFLOW.COM.S9A1.PSMTP.com", 25, $errno, $errstr, 30);
fwrite($smtp_server, "helo hi\r\n");
fwrite($smtp_server, "mail from: <me@myhost.com>\r\n");
fwrite($smtp_server, "rcpt to: <fake@stackoverflow.com>\r\n");
Drew Noakes answered 2019-07-12T16:16:28Z
8 votes

一般的答案是,如果您向其发送电子邮件,则无法检查电子邮件地址是否存在事件:它可能只是陷入黑洞。

可以说,那里描述的方法非常有效。 它在ZoneCheck的生产代码中使用,除了它使用RSET而不是QUIT。

如果用户与他的邮箱进行交互并不过分,那么许多网站实际上会通过发送必须发送回发射器的密码(通过转到秘密URL或通过电子邮件发回这个密码)来测试邮件到达某处。 大多数邮件列表都是这样的。

kmkaplan answered 2019-07-12T16:17:09Z
6 votes

不是真的.....某些服务器可能无法检查“rcpt to:”

[http://www.freesoft.org/CIE/RFC/1123/92.htm]

这样做是安全风险.....

如果服务器这样做,你可以编写一个bot来发现服务器上的每个地址....

l_39217_l answered 2019-07-12T16:18:00Z
5 votes

当目标邮件服务器使用灰名单时,这将失败(在其他情况下)。

灰名单:SMTP服务器在以前未知的客户端第一次连接时拒绝传递,允许下次(s); 这保留了一定比例的垃圾邮件,同时允许合法使用 - 因为预计合法邮件发件人将重试,这是普通邮件传输代理将执行的操作。

但是,如果您的代码仅检查服务器一次,则具有灰名单的服务器将拒绝传递(因为您的客户端是第一次连接); 除非您稍后再次检查,否则您可能会错误地拒绝有效的电子邮件地址。

Piskvor answered 2019-07-12T16:18:41Z
4 votes

一些问题:

  1. 我确定如果您提供的地址不存在,某些SMTP服务器会立即通知您,但有些服务器不会作为隐私措施。 他们只会接受你给他们的任何地址,并默默地忽略那些不存在的地址。
  2. 正如文章所说,如果您经常使用某些服务器执行此操作,他们会将您列入黑名单。
  3. 对于某些SMTP服务器(如gmail),您需要使用SSL才能执行任何操作。 仅当使用gmail的SMTP服务器发送电子邮件时才会这样。
Graeme Perrow answered 2019-07-12T16:19:40Z
3 votes
function EmailValidation($email)
{
    $email = htmlspecialchars(stripslashes(strip_tags($email))); //parse unnecessary characters to prevent exploits
    if (eregi('[a-z||0-9]@[a-z||0-9].[a-z]', $email)) {
        //checks to make sure the email address is in a valid format
        $domain = explode( "@", $email ); //get the domain name
        if (@fsockopen ($domain[1],80,$errno,$errstr,3)) {
            //if the connection can be established, the email address is probably valid
            echo "Domain Name is valid ";
            return true;
        } else {
            echo "Con not a email domian";
            return false; //if a connection cannot be established return false
        }
        return false; //if email address is an invalid format return false
    }
}
Sachin answered 2019-07-12T16:19:58Z
2 votes

“你能说出一个电子邮件客户/用户输入是否正确且存在吗?”

实际上这些是两个不同的东西。 它可能存在但可能不正确。

有时您必须使用面值的用户输入。 否则,有很多方法可以打败这个系统。

Learning answered 2019-07-12T16:20:41Z
2 votes

关于您所能做的就是搜索DNS并确保电子邮件地址中的域具有MX记录,除此之外没有可靠的方法来处理此问题。

某些服务器可能与您与SMTP服务器通信的rcpt-to方法一起使用,但它完全取决于服务器的配置。 另一个问题可能是重载服务器可能会返回550代码,说用户未知,但这是一个临时错误,有一个永久性错误(我认为是451?)可以返回。 这完全取决于服务器的配置。

我个人会检查DNS MX记录,然后发送电子邮件验证MX记录是否存在。

Bryan Rehbein answered 2019-07-12T16:21:25Z
2 votes

虽然这个问题有点陈旧,但此服务提示可能会帮助用户在发送之前搜索类似的解决方案,检查电子邮件地址,而不是语法验证。

我一直在使用这个开源服务来更深入地验证电子邮件(检查电子邮件地址域上的mx记录等),以获得一些效果良好的项目。 它还检查常见的拼写错误是非常有用的。 在这里演示。

Henkealg answered 2019-07-12T16:22:01Z
1 votes

假设它是用户的地址,某些邮件服务器确实允许SMTP VRFY命令实际验证其邮箱的电子邮件地址。 大多数主要网站都不会给你太多信息; gmail的回复是“如果你试图邮寄它,我们会尝试发送它”或类似的东西。

Austin Salonen answered 2019-07-12T16:22:28Z
1 votes

我认为你不能,有很多场景甚至发送电子邮件都会失败。 例如。 用户端的邮件服务器暂时关闭,邮箱存在但已满,因此无法传递邮件等。

这可能是在用户确认收到确认电子邮件之后,许多网站验证注册的原因。

PhiLho answered 2019-07-12T16:23:05Z
-6 votes
<?php

   $email = "someone@exa mple.com";

   if(!filter_var($email, FILTER_VALIDATE_EMAIL))
      echo "E-mail is not valid";
   else
      echo "E-mail is valid";

?>
user4314333 answered 2019-07-12T16:23:23Z
translate from https://stackoverflow.com:/questions/565504/how-to-check-if-an-email-address-exists-without-sending-an-email