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


120

我如何使用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; 
     }    
} 

但显示过时的错误。我该如何解决此问题。请帮我。


3
已经给出了正确的答案,但是关于不建议使用的问题:不建议使用POSIX正则表达式(eregi是的功能)。请改用PCRE
菲利克斯·克林

3
顺便说一句,您的正则表达式是完全错误的。您的功能会将某些完全有效的地址标记为无效。使用正则表达式过滤电子邮件地址是一场噩梦。
Artefact2

您应该使用RFC 822标准,这是一篇很好的文章,用PHP解析电子邮件地址对此进行了解释。
2014年

Answers:


275

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

filter_var($email, FILTER_VALIDATE_EMAIL)

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

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

注意:对于其他用途(需要Regex的地方),不赞成使用的ereg功能族(POSIX Regex Functions)应替换为该preg族(PCRE Regex Functions)。差异很小,阅读本手册就足够了。

更新1@binaryLV指出:

PHP 5.3.3和5.2.14有一个与FILTER_VALIDATE_EMAIL相关的bug,在验证大值时会导致segfault。在此strlen() 之前,使用简单安全的解决方法filter_var()。我不确定5.3.4最终版,但据记载,一些5.3.4快照版本也受到了影响。

该错误已得到修复。

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

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

正如@Eliseo Ocampos指出的那样,此问题仅在PHP 5.3之前存在,在该版本中,他们更改了正则表达式,现在它进行了此检查,因此您不必这样做。


4
+1也就是说,您可能要提及的是,此功能仅在PHP 5.2.x及更高版本中可用。:-)
约翰·帕克

5
@middaparka:由于OP收到了不推荐使用的消息eregi,看来他正在使用PHP 5.3。但是是的,(对其他人)提及它很重要。
菲利克斯·克林

8
PHP 5.3.3和5.2.14有一个与()有关的bug(bugs.php.net/52929FILTER_VALIDATE_EMAIL,当验证大值时会导致segfault。在此strlen()之前,使用简单安全的解决方法filter_val()。我不确定5.3.4最终版,但据记载,一些5.3.4快照版本也受到了影响。
binaryLV

1
@binaryLV,filter_val还是filter_var
Istiaque Ahmed

3
@kapa,实际上,您无需再检查域部分中的点。见svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/...
艾丽赛欧奥坎波斯


7

这是旧文章,但我将分享我的解决方案,因为之前没有人提到一个问题。

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

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

这就是为什么我为此提出解决方案的原因:

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;
        }
    }
}

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


3

我总是用这个:

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;
}

1
@unbreak我尝试了您的代码,发现如果您按原样传递电子邮件,alex@.那么在它不是有效的电子邮件地址的情况下,它始终会返回true。
Subhajit



0

用户数据对于一个好的开发人员来说非常重要,因此不要一再询问相同的数据,而要使用一些逻辑来纠正数据中的一些基本错误。

在验证电子邮件之前:首先,您必须从电子邮件中删除所有非法字符。

//This will Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);

之后,使用此filter_var()功能验证您的电子邮件地址。

filter_var($email, FILTER_VALIDATE_EMAIL)) // To Validate the email

例如

<?php
$email = "john.doe@example.com";

// Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);

// Validate email
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo $email." is a valid email address";
} else {
    echo $email." is not a valid email address";
}
?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.