我有这个功能来验证一个电子邮件地址:

function validateEMAIL($EMAIL) {
    $v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/";

    return (bool)preg_match($v, $EMAIL);
}

这样可以检查电子邮件地址是否有效吗?


当前回答

看完这里的答案后,我得出了以下结论:

public static function isValidEmail(string $email) : bool
{
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return false;
    }

    //Get host name from email and check if it is valid
    $email_host = array_slice(explode("@", $email), -1)[0];

    // Check if valid IP (v4 or v6). If it is we can't do a DNS lookup
    if (!filter_var($email_host,FILTER_VALIDATE_IP, [
        'flags' => FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE,
    ])) {
        //Add a dot to the end of the host name to make a fully qualified domain name
        // and get last array element because an escaped @ is allowed in the local part (RFC 5322)
        // Then convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
        $email_host = idn_to_ascii($email_host.'.');

        //Check for MX pointers in DNS (if there are no MX pointers the domain cannot receive emails)
        if (!checkdnsrr($email_host, "MX")) {
            return false;
        }
    }

    return true;
}

其他回答

看完这里的答案后,我得出了以下结论:

public static function isValidEmail(string $email) : bool
{
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return false;
    }

    //Get host name from email and check if it is valid
    $email_host = array_slice(explode("@", $email), -1)[0];

    // Check if valid IP (v4 or v6). If it is we can't do a DNS lookup
    if (!filter_var($email_host,FILTER_VALIDATE_IP, [
        'flags' => FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE,
    ])) {
        //Add a dot to the end of the host name to make a fully qualified domain name
        // and get last array element because an escaped @ is allowed in the local part (RFC 5322)
        // Then convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
        $email_host = idn_to_ascii($email_host.'.');

        //Check for MX pointers in DNS (if there are no MX pointers the domain cannot receive emails)
        if (!checkdnsrr($email_host, "MX")) {
            return false;
        }
    }

    return true;
}

如果你想检查电子邮件地址提供的域名是否有效,可以使用如下方法:

/*
* Check for valid MX record for given email domain
*/
if(!function_exists('check_email_domain')){
    function check_email_domain($email) {
        //Get host name from email and check if it is valid
        $email_host = explode("@", $email);     
        //Add a dot to the end of the host name to make a fully qualified domain name and get last array element because an escaped @ is allowed in the local part (RFC 5322)
        $host = end($email_host) . "."; 
        //Convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
        return checkdnsrr(idn_to_ascii($host), "MX"); //(bool)       
    }
}

这是一种方便的方式来过滤大量无效的电子邮件地址,以及标准的电子邮件验证,因为有效的电子邮件格式并不意味着有效的电子邮件。

请注意,idn_to_ascii()(或它的姐妹函数idn_to_utf8())函数在PHP安装中可能不可用,它需要扩展PECL intl >= 1.0.2和PECL idn >= 0.1。

还要记住,IPv4或IPv6作为电子邮件中的域部分(例如user@[IPv6:2001:db8::1])不能被验证,只有命名主机可以。

点击这里查看更多信息。

我准备了一个检查电子邮件有效性的函数:

function isValidEmail($email)
{
    $re = '/([\w\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)/m';
    preg_match_all($re, $email, $matches, PREG_SET_ORDER, 0);
    if(count($matches) > 0) return $matches[0][0] === $email;
    return false;
}

FILTER_VALIDATE_EMAIL的问题是,它甚至认为无效的电子邮件是有效的。

以下是例子:

if(isValidEmail("foo@gmail.com")) echo "valid";
if(!isValidEmail("fo^o@gmail.com")) echo "invalid";

检查电子邮件地址是否格式良好的最简单和最安全的方法是使用filter_var()函数:

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // invalid emailaddress
}

此外,您可以检查域是否定义了MX记录:

if (!checkdnsrr($domain, 'MX')) {
    // domain is not valid
}

但这仍然不能保证邮件存在。唯一的办法就是发送确认邮件。


现在你已经有了简单的答案,如果你想学习,可以继续阅读关于电子邮件地址验证的内容,或者只是使用快速答案并继续前进。别见怪不怪。

尝试使用正则表达式验证电子邮件地址是一项“不可能”的任务。我想说的是,你所做的正则表达式是无用的。关于电子邮件地址有三个rfc,编写一个正则表达式来捕获错误的电子邮件地址,同时避免误报,这是没有人能做到的。查看PHP的filter_var()函数所使用的正则表达式的测试列表(包括失败和成功)。

即使是内置的PHP函数,电子邮件客户端或服务器也没有做到这一点。在大多数情况下,filter_var仍然是最好的选择。

如果你想知道PHP(目前)使用哪种正则表达式模式来验证电子邮件地址,请参阅PHP源代码。

如果你想了解更多关于电子邮件地址的信息,我建议你开始阅读说明书,但我必须警告你,无论如何,这都不是一个简单的阅读:

rfc5322 rfc5321 rfc3696 Rfc6531(允许unicode字符,尽管许多客户端/服务器不接受它)

的Python和PHP实现 正确验证任何电子邮件地址,即 邮件服务器确认是真的 域是实的。

在GPL-3.0许可下发布。

就是这样:

https://lja.fi/index.php/github-stuff/

--李雅