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

Posted

技术标签:

【中文标题】如何在 PHP 中验证电子邮件?【英文标题】:How to validate an Email in PHP? 【发布时间】:2011-08-16 21:10:44 【问题描述】:

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

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

【问题讨论】:

已经给出了正确答案,但是关于 deprecated 问题:POSIX 正则表达式(eregi 是其中的一个函数)的使用已被弃用。请改用PCRE。 顺便说一句,你的正则表达式是完全错误的。某些完全有效的地址将被您的函数标记为无效。使用正则表达式过滤电子邮件地址是一场噩梦。 您应该使用RFC 822 标准,这里有一篇很好的文章Parsing Email Adresses in PHP 对此进行了解释。 远离regexfilter_var() 验证电子邮件的解决方案。看到这个答案:***.com/a/42037557/953833 【参考方案1】:

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

filter_var($email, FILTER_VALIDATE_EMAIL)

PHP Manual filter_var()

PHP >= 5.2.0

中可用

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

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 有一个 bug 相关 FILTER_VALIDATE_EMAIL,验证时导致段错误 大值。简单而安全的解决方法是使用strlen()filter_var() 之前。我不确定 5.3.4 final,但它是 写到一些 5.3.4-snapshot 版本也受到了影响。

这个错误已经修复了。

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

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

正如@Eliseo Ocampos 所指出的,这个问题只存在于 PHP 5.3 之前,in that version they changed the regex 现在它会做这个检查,所以你不必这样做。

【讨论】:

+1 也就是说,您可能想提一下,这仅在 PHP 5.2.x 及更高版本中可用。 :-) @middaparka:当 OP 收到 eregi 的弃用消息时,他似乎正在使用 PHP 5.3。但是,是的,重要的是(对其他人)提及它)。 PHP 5.3.3 和 5.2.14 有一个与 FILTER_VALIDATE_EMAIL 相关的错误 (bugs.php.net/52929),导致验证大值时出现段错误。简单而安全的解决方法是在filter_val() 之前使用strlen()。我不确定 5.3.4 的最终版本,但据说一些 5.3.4 快照版本也受到了影响。 @binaryLV、filter_valfilter_var ? @kapa,实际上您不再需要检查域部分中的点。见svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/…【参考方案2】:

查看http://www.php.net/manual/en/function.ereg.php的注释:

Note:

从 PHP 5.3.0 开始,不推荐使用正则表达式扩展,取而代之的是 PCRE extension。调用这个 函数将发出 E_DEPRECATED 注意。见the list of differences 寻求有关转换为 PCRE 的帮助。

Note:

preg_match(),使用 Perl 兼容的正则表达式 语法,通常是更快的选择 到 ereg()。

【讨论】:

【参考方案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;

【讨论】:

@unbreak 我试过你的代码,发现如果你以alex@. 的形式传递电子邮件,那么它总是返回true,它不是一个有效的电子邮件地址。【参考方案4】:

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

新的电子邮件地址可以包含 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;
        
    

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

【讨论】:

【参考方案5】:

用途:

或来自http://php.net/manual/en/function.filter-var.php的“filter_var”
var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));
或来自https://github.com/egulias/EmailValidator的“EmailValidator”
$validator = new EmailValidator();
$multipleValidations = new MultipleValidationWithAnd([
    new RFCValidation(),
    new DNSCheckValidation()
]);
$validator->isValid("example@example.com", $multipleValidations); //true

【讨论】:

【参考方案6】:

用户数据对于优秀的开发者来说非常重要,所以不要再问了 再次对于相同的数据,使用一些逻辑来纠正数据中的一些基本错误。

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

//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";

?>

【讨论】:

【参考方案7】:

注意,像 iasd@xz-----com 这样的地址是无效的,但是 filter_var() 返回 true,许多其他字符串(电子邮件)INVALIDS 使用 filter_var() 返回 true。

对于验证电子邮件,我使用此功能:

function correcorre($s)// correo correcto
    $x = '^([[:alnum:]](_|-|\.)*)*[[:alnum:]]+@([[:alnum:]]+(-|\.)+)*[[:alnum:]]+\.[[:alnum:]]+$';
    preg_match("!$x!i", $s, $M);
    if(!empty($M[0]))return($M[0]);
    

请改进和分享,谢谢

【讨论】:

以上是关于如何在 PHP 中验证电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

当使用 PHP 在后端验证电子邮件时,如何将输入提交从禁用更改为启用?

AJAX 实时电子邮件验证 (PHP)

使用 JQuery、Ajax、PHP、Json 进行表单验证

PHP 电子邮件有效。在PHP中验证电子邮件地址

在php中验证电子邮件[重复]

在 PHP 中验证电子邮件地址 [重复]