如何在 PHP 中验证电子邮件地址
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12026842/
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
How to validate an email address in PHP
提问by Cameron
I have this function to validate an email addresses:
我有这个功能来验证电子邮件地址:
function validateEMAIL($EMAIL) {
$v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/";
return (bool)preg_match($v, $EMAIL);
}
Is this okay for checking if the email address is valid or not?
这可以检查电子邮件地址是否有效吗?
回答by PeeHaa
The easiest and safest way to check whether an email address is well-formed is to use the filter_var()function:
检查电子邮件地址是否格式正确的最简单和最安全的方法是使用以下filter_var()函数:
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// invalid emailaddress
}
Additionally you can check whether the domain defines an MXrecord:
此外,您可以检查域是否定义了MX记录:
if (!checkdnsrr($domain, 'MX')) {
// domain is not valid
}
But this still doesn't guarantee that the mail exists. The only way to find that out is by sending a confirmation mail.
但这仍然不能保证邮件存在。找出这一点的唯一方法是发送确认邮件。
Now that you have your easy answer feel free to read on about email address validation if you care to learn or otherwise just use the fast answer and move on. No hard feelings.
现在您有了简单的答案,如果您想学习或仅使用快速答案并继续前进,请随时阅读有关电子邮件地址验证的内容。别往心里放。
Trying to validate an email address using a regex is an "impossible" task. I would go as far as to say that that regex you have made is useless. There are three rfc's regarding emailaddresses and writing a regex to catch wrong emailadresses and at the same time don't have false positives is something no mortal can do. Check out this listfor tests (both failed and succeeded) of the regex used by PHP's filter_var()function.
尝试使用正则表达式验证电子邮件地址是一项“不可能”的任务。我什至会说您制作的正则表达式毫无用处。关于电子邮件地址和编写正则表达式以捕获错误的电子邮件地址,有三个 rfc,同时没有误报是凡人无法做到的。查看此列表以获取 PHPfilter_var()函数使用的正则表达式的测试(失败和成功)。
Even the built-in PHP functions, email clients or servers don't get it right. Still in most cases filter_varis the best option.
即使是内置的 PHP 函数、电子邮件客户端或服务器也无法正确处理。在大多数情况下仍然filter_var是最好的选择。
If you want to know which regex pattern PHP (currently) uses to validate email addresses see the PHP source.
如果您想知道 PHP(当前)使用哪种正则表达式模式来验证电子邮件地址,请参阅PHP 源代码。
If you want to learn more about email addresses I suggest you to start reading the specs, but I have to warn you it is not an easy read by any stretch:
如果您想了解有关电子邮件地址的更多信息,我建议您开始阅读规范,但我必须警告您,无论如何都不容易阅读:
- rfc5322
- rfc5321
- rfc3696
- rfc6531(allows unicode characters, although many clients / servers don't accept it)
Note that filter_var()is as already stated only available as of PHP 5.2. In case you want it to work with earlier versions of PHP you could use the regex used in PHP:
请注意,filter_var()正如已经说明的那样,仅在 PHP 5.2 中可用。如果您希望它与早期版本的 PHP 一起使用,您可以使用 PHP 中使用的正则表达式:
<?php
$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';
$emailaddress = '[email protected]';
if (preg_match($pattern, $emailaddress) === 1) {
// emailaddress is valid
}
P.S. A note on the regex pattern used above (from the PHP source). It looks like there is some copyright on it of Michael Rushton. As stated: "Feel free to use and redistribute this code. But please keep this copyright notice."
PS 关于上面使用的正则表达式模式的注释(来自 PHP 源代码)。看起来Michael Rushton有一些版权。如所述:“随意使用和重新分发此代码。但请保留此版权声明。”
回答by Cameron Martin
You can use filter_varfor this.
您可以为此使用filter_var。
<?php
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
?>
回答by Jabari
In my experience, regexsolutions have too many false positives and filter_var()solutions have false negatives (especially with all of the newer TLDs).
根据我的经验,regex解决方案有太多误报,而filter_var()解决方案有误报(尤其是对于所有较新的TLD)。
Instead, it's better to make sure the address has all of the required parts of an email address (user, "@" symbol, and domain), then verify that the domain itself exists.
相反,最好确保该地址具有电子邮件地址的所有必需部分(用户、“@”符号和域),然后验证域本身是否存在。
There is no way to determine (server side) if an email user exists for an external domain.
无法确定(服务器端)是否存在外部域的电子邮件用户。
This is a method I created in a Utility class:
这是我在 Utility 类中创建的方法:
public static function validateEmail($email)
{
// SET INITIAL RETURN VARIABLES
$emailIsValid = FALSE;
// MAKE SURE AN EMPTY STRING WASN'T PASSED
if (!empty($email))
{
// GET EMAIL PARTS
$domain = ltrim(stristr($email, '@'), '@') . '.';
$user = stristr($email, '@', TRUE);
// VALIDATE EMAIL ADDRESS
if
(
!empty($user) &&
!empty($domain) &&
checkdnsrr($domain)
)
{$emailIsValid = TRUE;}
}
// RETURN RESULT
return $emailIsValid;
}
回答by Fluffeh
回答by Excalibur
This will not only validate your email, but also sanitize it for unexpected characters:
这不仅可以验证您的电子邮件,还可以清除意外字符:
$email = $_POST['email'];
$emailB = filter_var($email, FILTER_SANITIZE_EMAIL);
if (filter_var($emailB, FILTER_VALIDATE_EMAIL) === false ||
$emailB != $email
) {
echo "This email adress isn't valid!";
exit(0);
}
回答by FlameStorm
Answered this in 'top question' about emails verification https://stackoverflow.com/a/41129750/1848217
在关于电子邮件验证的“热门问题”中回答了这个问题https://stackoverflow.com/a/41129750/1848217
For me the right way for checking emails is:
- Check that symbol @ exists, and before and after it there are some non-@ symbols:
/^[^@]+@[^@]+$/- Try to send an email to this address with some "activation code".
- When the user "activated" his email address, we will see that all is right.
Of course, you can show some warning or tooltip in front-end when user typed "strange" email to help him to avoid common mistakes, like no dot in domain part or spaces in name without quoting and so on. But you must accept the address "hello@world" if user really want it.
Also, you must remember that email address standard was and can evolute, so you can't just type some "standard-valid" regexp once and for all times. And you must remember that some concrete internet servers can fail some details of common standard and in fact work with own "modified standard".
对我来说,检查电子邮件的正确方法是:
- 检查符号@ 是否存在,并且在它前后有一些非@ 符号:
/^[^@]+@[^@]+$/- 尝试向此地址发送一封带有一些“激活码”的电子邮件。
- 当用户“激活”他的电子邮件地址时,我们将看到一切正常。
当然,您可以在用户输入“奇怪”电子邮件时在前端显示一些警告或工具提示,以帮助他避免常见错误,例如域部分没有点或名称中没有引用的空格等。但是如果用户真的想要它,你必须接受地址“hello@world”。
此外,您必须记住电子邮件地址标准曾经并且可以演变,因此您不能一劳永逸地键入一些“标准有效”的正则表达式。并且您必须记住,某些具体的 Internet 服务器可能无法满足通用标准的某些细节,并且实际上可以使用自己的“修改后的标准”。
So, just check @, hint user on frontend and send verification emails on given address.
因此,只需检查@,在前端提示用户并在给定地址上发送验证电子邮件。
回答by Bud Damyanov
If you want to check if provided domain from email addressis valid, use something like:
如果要检查电子邮件地址提供的域是否有效,请使用以下内容:
/*
* Check for valid MX record for given email domain
*/
if(!function_exists('check_email_domain')){
function check_email_domain($email) {
//Get host name from email and check if it is valid
$email_host = explode("@", $email);
//Add a dot to the end of the host name to make a fully qualified domain name and get last array element because an escaped @ is allowed in the local part (RFC 5322)
$host = end($email_host) . ".";
//Convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
return checkdnsrr(idn_to_ascii($host), "MX"); //(bool)
}
}
This is handy way to filter a lot of invalid email addresses, along with standart email validation, because valid email formatdoes not mean valid email.
这是过滤大量无效电子邮件地址以及标准电子邮件验证的便捷方法,因为有效的电子邮件格式并不意味着有效的电子邮件。
Note that idn_to_ascii()(or his sister function idn_to_utf8()) function may not beavailable in your PHP installation, it requires extensions PECL intl >= 1.0.2 and PECL idn >= 0.1.
请注意,idn_to_ascii()(或他的姊妹函数idn_to_utf8())函数在您的 PHP 安装中可能不可用,它需要扩展 PECL intl >= 1.0.2 和 PECL idn >= 0.1。
Also keep in mind that IPv4 or IPv6 as domain part in email (for example user@[IPv6:2001:db8::1]) cannot be validated, only namedhosts can.
另请记住,user@[IPv6:2001:db8::1]无法验证IPv4 或 IPv6 作为电子邮件中域的一部分(例如),只有命名主机可以。
See more here.
回答by Pelmered
After reading the answers here, this is what I ended up with:
阅读这里的答案后,这就是我的结论:
public static function isValidEmail(string $email) : bool
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return false;
}
//Get host name from email and check if it is valid
$email_host = array_slice(explode("@", $email), -1)[0];
// Check if valid IP (v4 or v6). If it is we can't do a DNS lookup
if (!filter_var($email_host,FILTER_VALIDATE_IP, [
'flags' => FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE,
])) {
//Add a dot to the end of the host name to make a fully qualified domain name
// and get last array element because an escaped @ is allowed in the local part (RFC 5322)
// Then convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
$email_host = idn_to_ascii($email_host.'.');
//Check for MX pointers in DNS (if there are no MX pointers the domain cannot receive emails)
if (!checkdnsrr($email_host, "MX")) {
return false;
}
}
return true;
}
回答by smulholland2
If you're just looking for an actual regex that allows for various dots, underscores and dashes, it as follows: [a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+. That will allow a fairly stupid looking email like tom_anderson.1-neo@my-mail_matrix.comto be validated.
如果你只是寻找一个实际的正则表达式,它允许不同点,下划线和破折号,它如下:[a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+。这将允许tom_anderson.1-neo@my-mail_matrix.com验证看起来相当愚蠢的电子邮件。
回答by Thielicious
/(?![[:alnum:]]|@|-|_|\.)./
Nowadays, if you use a HTML5 form with type=emailthen you're already by 80% safe since browser engines have their own validator. To complement it, add this regex to your preg_match_all()and negate it:
如今,如果您使用 HTML5 表单,type=email那么您已经有 80% 的安全性,因为浏览器引擎有自己的验证器。为了补充它,将此正则表达式添加到您的preg_match_all()并否定它:
if (!preg_match_all("/(?![[:alnum:]]|@|-|_|\.)./",$email)) { .. }
Find the regex used by HTML5 forms for validation
https://regex101.com/r/mPEKmy/1

