如何在 PHP 中验证电子邮件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5855811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 22:42:12  来源:igfitidea点击:

How to validate an Email in PHP?

phpregexvalidationemail-validation

提问by learner

How can I validate the input value is a valid email address using php5. Now I am using this code

如何使用php5验证输入值是有效的电子邮件地址。现在我正在使用此代码

function isValidEmail($email){ 
     $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"; 

     if (eregi($pattern, $email)){ 
        return true; 
     } 
     else { 
        return false; 
     }    
} 

but it shows deprecated error. How can I fix this issue. Please help me.

但它显示已弃用的错误。我该如何解决这个问题。请帮我。

回答by kapa

You can use the filter_var()function, which gives you a lot of handy validation and sanitization options.

您可以使用该filter_var()功能,它为您提供了许多方便的验证和清理选项。

filter_var($email, FILTER_VALIDATE_EMAIL)

If you don't want to change your code that relied on your function, just do:

如果您不想更改依赖于您的函数的代码,请执行以下操作:

function isValidEmail($email){ 
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

Note: For other uses (where you need Regex), the deprecated eregfunction family (POSIX Regex Functions) should be replaced by the pregfamily (PCRE Regex Functions). There are a small amount of differences, reading the Manual should suffice.

注意:对于其他用途(需要 Regex 的地方),不推荐使用的ereg函数系列 (POSIX Regex Functions) 应替换为preg系列 ( PCRE Regex Functions)。有少量差异,阅读手册就足够了。

Update 1: As pointed out by @binaryLV:

更新 1:正如@binaryLV所指出的:

PHP 5.3.3 and 5.2.14 had a bugrelated to FILTER_VALIDATE_EMAIL, which resulted in segfault when validating large values. Simple and safe workaround for this is using strlen()before filter_var(). I'm not sure about 5.3.4 final, but it is written that some 5.3.4-snapshot versions also were affected.

PHP 5.3.3 和 5.2.14 有一个与 FILTER_VALIDATE_EMAIL 相关的错误,这会导致在验证大值时出现段错误。简单而安全的解决方法是使用strlen()before filter_var()。我不确定 5.3.4 最终版的情况,但据说某些 5.3.4 快照版本也受到了影响。

This bug has already been fixed.

这个bug已经修复了。

Update 2: This method will of course validate bazmega@kapaas a valid email address, because in fact it is a valid email address. But most of the time on the Internet, you also want the email address to have a TLD: [email protected]. As suggested in this blog post(link posted by @Istiaque Ahmed), you can augment filter_var()with a regex that will check for the existence of a dot in the domain part (will not check for a validTLD though):

更新 2:此方法当然会验证bazmega@kapa为有效的电子邮件地址,因为实际上它是一个有效的电子邮件地址。但大多数时候在 Internet 上,您还希望电子邮件地址具有 TLD:[email protected]. 正如这篇博文@Istiaque Ahmed发布的链接)中所建议的那样,您可以filter_var()使用一个正则表达式进行扩充,该正则表达式将检查域部分中是否存在点(但不会检查有效的TLD):

function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) 
        && preg_match('/@.+\./', $email);
}

As @Eliseo Ocampospointed out, this problem only exists before PHP 5.3, in that version they changed the regexand now it does this check, so you do not have to.

正如@Eliseo Ocampos 所指出的,这个问题只存在于 PHP 5.3 之前,在那个版本中他们改变了正则表达式,现在它会进行这个检查,所以你不必这样做。

回答by Sean Kelleher

See the notes at http://www.php.net/manual/en/function.ereg.php:

请参阅http://www.php.net/manual/en/function.ereg.php 上的注释:

Note:

As of PHP 5.3.0, the regex extension is deprecated in favor of the PCRE extension. Calling this function will issue an E_DEPRECATED notice. See the list of differencesfor help on converting to PCRE.

Note:

preg_match(), which uses a Perl-compatible regular expression syntax, is often a faster alternative to ereg().

Note:

从 PHP 5.3.0 开始,regex 扩展已被弃用,取而代之的是PCRE 扩展。调用此函数将发出 E_DEPRECATED 通知。有关 转换为 PCRE 的帮助,请参阅差异列表

Note:

preg_match()使用与 Perl 兼容的正则表达式语法,通常是 ereg() 的更快替代方法。

回答by Ivijan Stefan Stipi?

This is old post but I will share one my solution because noone mention here one problem before.

这是旧帖子,但我会分享一个我的解决方案,因为之前没有人在这里提到过一个问题。

New email address can contain UTF-8 characters or special domain names like .live, .newsetc.

新的电子邮件地址可以包含UTF-8字符或特殊域名,如.live.news等。

Also I find that some email address can be on Cyrilic and on all cases standard regex or filter_var()will fail.

此外,我发现某些电子邮件地址可以使用 Cyrilic,并且在所有情况下都可以使用标准正则表达式,否则filter_var()会失败。

That's why I made an solution for it:

这就是为什么我为它制定了解决方案:

function valid_email($email) 
{
    if(is_array($email) || is_numeric($email) || is_bool($email) || is_float($email) || is_file($email) || is_dir($email) || is_int($email))
        return false;
    else
    {
        $email=trim(strtolower($email));
        if(filter_var($email, FILTER_VALIDATE_EMAIL)!==false) return $email;
        else
        {
            $pattern = '/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD';
            return (preg_match($pattern, $email) === 1) ? $email : false;
        }
    }
}

This function work perfectly for all cases and email formats.

此功能适用于所有案例和电子邮件格式。

回答by unbreak

I always use this:

我总是用这个:

function validEmail($email){
    // First, we check that there's one @ symbol, and that the lengths are right
    if (!preg_match("/^[^@]{1,64}@[^@]{1,255}$/", $email)) {
        // Email invalid because wrong number of characters in one section, or wrong number of @ symbols.
        return false;
    }
    // Split it into sections to make life easier
    $email_array = explode("@", $email);
    $local_array = explode(".", $email_array[0]);
    for ($i = 0; $i < sizeof($local_array); $i++) {
        if (!preg_match("/^(([A-Za-z0-9!#$%&'*+\/=?^_`{|}~-][A-Za-z0-9!#$%&'*+\/=?^_`{|}~\.-]{0,63})|(\"[^(\|\")]{0,62}\"))$/", $local_array[$i])) {
            return false;
        }
    }
    if (!preg_match("/^\[?[0-9\.]+\]?$/", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name
        $domain_array = explode(".", $email_array[1]);
        if (sizeof($domain_array) < 2) {
            return false; // Not enough parts to domain
        }
        for ($i = 0; $i < sizeof($domain_array); $i++) {
            if (!preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/", $domain_array[$i])) {
                return false;
            }
        }
    }

    return true;
}

回答by Jabari

Stay away from regexand filter_var()solutions for validating email. See this answer: https://stackoverflow.com/a/42037557/953833

从远点regexfilter_var()用于验证电子邮件解决方案。看到这个答案:https: //stackoverflow.com/a/42037557/953833

回答by Roman

Use:

用:

var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
$validator = new EmailValidator();
$multipleValidations = new MultipleValidationWithAnd([
    new RFCValidation(),
    new DNSCheckValidation()
]);
$validator->isValid("[email protected]", $multipleValidations); //true