如何在 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 对此进行了解释。
远离regex
和filter_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_val
或 filter_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 在后端验证电子邮件时,如何将输入提交从禁用更改为启用?