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

lea*_*ner 117 php regex validation email-validation

如何使用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; 
     }    
} 
Run Code Online (Sandbox Code Playgroud)

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

kap*_*apa 268

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

filter_var($email, FILTER_VALIDATE_EMAIL)
Run Code Online (Sandbox Code Playgroud)

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

function isValidEmail($email){ 
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
Run Code Online (Sandbox Code Playgroud)

注意:对于其他用途(需要Regex的地方),不推荐使用的ereg函数系列(POSIX正则表达式函数)应由preg系列替换(PCRE正则表达式函数).存在少量差异,阅读手册应该足够了.

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

PHP 5.3.3和5.2.14有一个与FILTER_VALIDATE_EMAIL相关的错误,在验证大值时会导致段错误.简单而安全的解决方法就是使用strlen() 之前filter_var().我不确定5.3.4 final,但是有人写了一些5.3.4快照版本也受到了影响.

这个bug已经修复了.

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

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

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

  • PHP 5.3.3和5.2.14有一个与`FILTER_VALIDATE_EMAIL`相关的错误(http://bugs.php.net/52929),在验证大值时会导致段错误.简单而安全的解决方法是在`filter_val()`之前使用`strlen()`.我不确定5.3.4 final,但是有人写了一些5.3.4快照版本也受到了影响. (8认同)
  • @middaparka:由于OP得到了一个弃用的消息"eregi",似乎他正在使用PHP 5.3.但是,重要的是要提到它(对于其他人)). (5认同)
  • +1那说,您可能要提到这只适用于PHP 5.2.x及更高版本.:-) (4认同)
  • @kapa,实际上您不再需要检查域部分中的点.见http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/logical_filters.c?r1=297250&r2=297350&pathrev=303779 (3认同)

Sea*_*her 9

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

Note:
Run Code Online (Sandbox Code Playgroud)

从PHP 5.3.0开始,不推荐使用正则表达式扩展,以支持PCRE扩展.调用此函数将发出E_DEPRECATED通知.有关 转换为PCRE的帮助,请参阅差异列表.

Note:
Run Code Online (Sandbox Code Playgroud)

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


Ivi*_*pić 6

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

新的电子邮件地址可以包含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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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