如何使用PHP检查电子邮件地址是否真实或有效

66

我找到了一些声称可以验证电子邮件地址是否有效的网站。仅使用 PHP 是否有可能检查电子邮件地址是否有效?

<?php
    if($_POST['email'] != ''){
        // The email to validate
        $email = $_POST['email'];

        // An optional sender
        function domain_exists($email, $record = 'MX'){
            list($user, $domain) = explode('@', $email);
            return checkdnsrr($domain, $record);
        }
        if(domain_exists($email)) {
            echo('This MX records exists; I will accept this email as valid.');
        }
        else {
            echo('No MX record exists;  Invalid email.');
        }
    }
?>
<form method="POST">
    <input type="text" name="email">
    <input type="submit" value="submit">
</form>

这是我现在拥有的内容。 它检查域名是否存在但无法检查用户的电子邮件是否存在于该域中。使用PHP可以实现吗?


4
好的,给他们发送一封电子邮件并查看是否有回应。否则不行,因为存在垃圾邮件发送者。 - Hamish
4
验证电子邮件地址的唯一可靠方法是向其发送电子邮件。即使您验证了MX记录,也不能可靠地查询服务器,因为大多数电子邮件服务器不会响应查询。感谢您友好的垃圾邮件发送者造成的这种情况。 - user1864610
1
https://dev59.com/snRB5IYBdhLWcg3wpYio#566121 - scrowler
5
你无法做到100%。看看这些人是如何做到的:https://code.google.com/p/php-smtp-email-validation/. 这是最彻底的方法了。 - Casey
首先,您需要检查该电子邮件地址的MX记录。完成后,您需要检查SMTP。我遵循了下面提到的文章,并且脚本就像魔法一样运行:http://www.phpwala.in/php/how-to-check-if-an-email-address-is-real-or-not-php/2018/01 - Lalit Giriya
也许这个网站可以帮到你:https://checkeremail.com/ - snex
4个回答

48

使用单一的PHP方法无法对电子邮件的存在性进行足够准确的验证,您可以向该帐户发送电子邮件,但仅此并不能证明该帐户存在(请参见下文)。至少,您可以验证它的格式正确。

if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
    //Email is valid
}

如果你想的话,可以添加另一个检查。解析域名并运行checkdnsrr

if(checkdnsrr($domain)) {
     // Domain at least has an MX record, necessary to receive email
}

许多人到达这一点时,仍然不相信没有隐藏的方法。如果您坚决要验证电子邮件,请考虑以下一些注意事项:

  1. 垃圾邮件发送者也知道"连接技巧"(即您开始发送电子邮件并依赖服务器在那一点上反弹)。其中一个其他答案链接到 此库,该库有此警告。

    一些邮件服务器将默默地拒绝测试消息,以防止垃圾邮件发送者检查其用户的电子邮件并过滤有效的电子邮件,因此此功能可能无法正确工作所有邮件服务器。

    换句话说,如果有无效地址,您可能不会收到无效地址的响应。事实上,几乎所有邮件服务器都带有接受所有传入邮件的选项 (这是如何使用Postfix进行设置的)。链接到验证库的答案忽略了该警告。

  2. 垃圾邮件黑名单。他们按IP地址列入黑名单,如果您的服务器不断进行验证连接,则有可能被列入Spamhaus或另一个阻止列表。如果您被列入黑名单,那么验证电子邮件地址有什么好处呢?

  3. 如果真的很重要验证电子邮件地址,则应强制用户响应电子邮件。向他们发送一封完整的电子邮件,并包含一个链接,他们必须点击该链接以进行验证。这不具有垃圾邮件的性质,并且您保证任何响应都具有有效的地址。


3
这并不检查电子邮件是否存在,它只是像正则表达式验证。 - Kamal Saleh
7
他并没有建议检查电子邮件是否存在,只是验证其格式是否正确。 - Andrew Killen
4
正如我在答案中所说,没有绝对可靠的方法可以检查电子邮件是否存在。并非每个服务器都会告诉您尝试向其发送电子邮件的帐户无效,如果您开始向服务器发送垃圾测试请求,则可能会被列入黑名单(即Spamhaus等)。 - Machavity
2
@BarışKURT 如果sss.com愉快地接受两者并且没有告诉你不存在的那个,那该怎么办呢?我一直很惊讶于坚持认为有某种神奇的方法可以确定所有电子邮件是否存在。有些服务器会告诉您它是否存在,但是许多服务器不会 - Machavity
1
顺便说一下,我的点赞并不是因为简单的验证,任何人都应该毫不犹豫地进行验证,而是因为正确地观察到您永远不能依靠服务器响应来确定电子邮件帐户状态。如果可以的话,全世界的垃圾邮件发送者都会使用这种方法来验证他们的电子邮件数据库,以避免发送到无效的电子邮件地址,这会浪费他们的金钱。事实上,他们不使用这些方法,而是依赖于带有查询字符串的服务器托管图像或点击链接来验证电子邮件,这实际上就足以说明它是行不通的。 - Lizardx
显示剩余3条评论

48
更新2023:如果这仍然有效,今天这将导致您被屏蔽。请查看评论。

您应该与SMTP进行检查。

这意味着您必须连接到该电子邮件的SMTP服务器。

连接到SMTP服务器后,您应该发送以下命令:

HELO somehostname.example
MAIL FROM: <no-reply@gmail.com>
RCPT TO: <emailtovalidate@domain.example>

如果你收到的邮件是“ Relay access denied”,那就意味着这个邮箱是无效的。
有一个简单的PHP类可以帮助你,你可以使用它:

http://www.phpclasses.org/package/6650-PHP-Check-if-an-e-mail-is-valid-using-SMTP.html


3
这个脚本很棒,但是当我在 Outlook、Live 和 Hotmail 服务器上测试时,存在的邮件会出现响应代码554,然后脚本会挂起直到超时。 - TMMDev
5
我尝试了这个课程,每一个有效的电子邮件都返回“有效,但不存在!” - Sola Oderinde
10
从技术上讲这是正确的,但实际上不建议这么做:网络服务提供商(尤其是雅虎和Hotmail)知道这一点,如果你经常这样做,他们将会阻止你的邮件投递(即使是发送到真实存在的地址)。简而言之,不要这样做。 - Synchro
1
也许你检查的电子邮件有一个万能收件箱条目。 通过这个条目,您可以配置邮件服务器将未被现有电子邮件地址捕获的每封电子邮件重定向到此电子邮件帐户。 因此,即使没有单独的邮箱用于此电子邮件地址,每个语法正确的电子邮件地址对于该服务器也是有效的。 - Alexander Behling
1
请仅使用其他方法对邮件进行语法验证。从2023年开始,将不再有可靠的技术方式来验证邮件地址的存在(除非发送到该地址)- 如果有的话,这将成为垃圾邮件发送者更多地发送垃圾邮件的好方法。 - Alex

4
我整个上午一直在寻找同样的答案,基本上已经发现了如果您需要验证的每个电子邮件地址是否实际存在于您需要验证它的时间,则很可能无法验证。因此,作为解决方法,我创建了一个简单的PHP脚本,用于验证电子邮件地址的格式是否正确,并且还验证使用的域名也是正确的。 GitHub链接在这里:https://github.com/DukeOfMarshall/PHP---JSON-Email-Verification/tree/master
<?php

# What to do if the class is being called directly and not being included in a script     via PHP
# This allows the class/script to be called via other methods like JavaScript

if(basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])){
$return_array = array();

if($_GET['address_to_verify'] == '' || !isset($_GET['address_to_verify'])){
    $return_array['error']              = 1;
    $return_array['message']            = 'No email address was submitted for verification';
    $return_array['domain_verified']    = 0;
    $return_array['format_verified']    = 0;
}else{
    $verify = new EmailVerify();

    if($verify->verify_formatting($_GET['address_to_verify'])){
        $return_array['format_verified']    = 1;

        if($verify->verify_domain($_GET['address_to_verify'])){
            $return_array['error']              = 0;
            $return_array['domain_verified']    = 1;
            $return_array['message']            = 'Formatting and domain have been verified';
        }else{
            $return_array['error']              = 1;
            $return_array['domain_verified']    = 0;
            $return_array['message']            = 'Formatting was verified, but verification of the domain has failed';
        }
    }else{
        $return_array['error']              = 1;
        $return_array['domain_verified']    = 0;
        $return_array['format_verified']    = 0;
        $return_array['message']            = 'Email was not formatted correctly';
    }
}

echo json_encode($return_array);

exit();
}

class EmailVerify {
public function __construct(){

}

public function verify_domain($address_to_verify){
    // an optional sender  
    $record = 'MX';
    list($user, $domain) = explode('@', $address_to_verify);
    return checkdnsrr($domain, $record);
}

public function verify_formatting($address_to_verify){
    if(strstr($address_to_verify, "@") == FALSE){
        return false;
    }else{
        list($user, $domain) = explode('@', $address_to_verify);

        if(strstr($domain, '.') == FALSE){
            return false;
        }else{
            return true;
        }
    }
    }
}
?>

1
这并不检查电子邮件是否存在,而是检查MX记录是否存在且正常工作。本周完成此任务,请访问https://github.com/hbattat/verifyEmail。 - Sam Battat

1
截至2023年,应该没有可靠的技术方法来检查邮件地址的存在。如果有的话,这将是垃圾邮件发送者更多发送垃圾邮件的好办法,因为他们可以轻松扫描有效的电子邮件地址。
唯一的方法是发送选择性订阅邮件。这不仅可以检查地址是否存在,还可以确认它是否为用户正确的地址。如果地址存在但属于其他人也无济于事。在欧洲等一些国家,这甚至是法律要求的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接