我具有此功能来验证电子邮件地址:
function validateEMAIL($EMAIL) {
$v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/";
return (bool)preg_match($v, $EMAIL);
}
可以检查电子邮件地址是否有效吗?
我具有此功能来验证电子邮件地址:
function validateEMAIL($EMAIL) {
$v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/";
return (bool)preg_match($v, $EMAIL);
}
可以检查电子邮件地址是否有效吗?
Answers:
检查电子邮件地址格式是否正确的最简单,最安全的方法是使用以下filter_var()
功能:
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// invalid emailaddress
}
此外,您可以检查域是否定义了一条MX
记录:
if (!checkdnsrr($domain, 'MX')) {
// domain is not valid
}
但这仍然不能保证邮件的存在。找出此错误的唯一方法是发送确认邮件。
既然您已经有了简单的答案,则可以随时阅读有关电子邮件地址验证的内容,如果您想学习还是以其他方式使用快速答案继续进行下去。别往心里放。
尝试使用正则表达式验证电子邮件地址是一项“不可能”的任务。我要说的是,您制作的正则表达式是没有用的。关于电子邮件地址和编写正则表达式以捕获错误的电子邮件地址,共有三个RFC,同时没有误报是凡人无法做的。签出此列表以测试PHP filter_var()
函数使用的正则表达式的测试(失败和成功)。
即使是内置的PHP函数,电子邮件客户端或服务器也无法正确使用它。在大多数情况下,仍然filter_var
是最佳选择。
如果您想知道PHP当前使用哪种正则表达式模式来验证电子邮件地址,请参阅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 = 'test@gmail.com';
if (preg_match($pattern, $emailaddress) === 1) {
// emailaddress is valid
}
PS关于上面使用的正则表达式模式的注释(来自PHP源代码)。看起来Michael Rushton拥有版权。如前所述:“可以随意使用和重新分发此代码。但是请保留此版权声明。”
filter_var
即使他们现在改变了它,也将落后相当一段时间(我已经发布了一个错误报告)。
您可以为此使用filter_var。
<?php
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
?>
以我的经验,regex
解决方案有太多的误报,而解决方案有很多误报filter_var()
(尤其是对于所有较新的TLD而言)。
相反,最好确保该地址具有电子邮件地址的所有必需部分(用户,“ @”符号和域),然后验证域本身是否存在。
无法确定(服务器端)是否存在用于外部域的电子邮件用户。
这是我在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;
}
stristr
如果有多个@符号,将无法获取域。最好explode('@',$email)
检查一下sizeof($array)==2
checkdnsrr()
如果域中有@符号,则该方法仍将返回false 。
在有关电子邮件验证的“首要问题”中回答了此问题https://stackoverflow.com/a/41129750/1848217
对我来说,检查电子邮件的正确方法是:
- 检查符号@是否存在,并且在其前后有一些非@符号:
/^[^@]+@[^@]+$/
- 尝试通过一些“激活码”将电子邮件发送到该地址。
- 当用户“激活”他的电子邮件地址时,我们将看到一切正确。
当然,当用户键入“奇怪的”电子邮件时,您可以在前端显示一些警告或工具提示,以帮助他避免常见的错误,例如域部分中没有点或名称中没有引号的空格等。但是,如果用户确实需要,您必须接受地址“ hello @ world”。
此外,您还必须记住,电子邮件地址标准曾经而且可能会不断发展,因此,您不能一劳永逸地只键入一些“标准有效”的正则表达式。您必须记住,某些具体的Internet服务器可能会使通用标准的某些细节失效,并且实际上可以使用自己的“修改后的标准”。
因此,只需选中@,在前端提示用户并在给定地址上发送验证电子邮件即可。
@
,但实际上并不会根据管理电子邮件的任何RFC来检查其是否有效。它也不能按书面规定工作。我通过regex101.com运行它,但它与有效地址不匹配
/^[^@]+@[^@+]$/
为/^[^@]+@[^@]+$/
filter_var
方法相比有何改进?它也不能解决接受格式错误的地址的问题。您的正则表达式会很乐意接受joe@domain
有效的电子邮件地址(如果不是)
filter_var($email, FILTER_VALIDATE_EMAIL, $newOptions)
。但是您在服务器上具有旧功能,在某些情况下无法更新。然后,您将使用一些新的有效电子邮件来失去客户。另外,我再次注意到,并非所有的电子邮件服务服务器都严格按照通用和现代的电子邮件地址标准工作。
如果要检查从电子邮件地址提供的域是否有效,请使用以下方法:
/*
* 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)
}
}
这是过滤大量无效电子邮件地址以及标准电子邮件验证的简便方法,因为有效的电子邮件格式并不意味着有效的电子邮件。
请注意,idn_to_ascii()
(或他的姐妹函数idn_to_utf8()
)函数在您的PHP安装中可能不可用,它需要扩展PECL intl> = 1.0.2和PECL idn> = 0.1。
另外请记住,user@[IPv6:2001:db8::1]
不能验证IPv4或IPv6作为电子邮件中的域部分(例如),只有命名主机可以被验证。
在这里查看更多。
在这里阅读答案之后,这就是我的结论:
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;
}
如果您只是在寻找可包含各种点,下划线和破折号的实际正则表达式,则如下所示:[a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+
。这样tom_anderson.1-neo@my-mail_matrix.com
可以验证看起来相当愚蠢的电子邮件。
/(?![[:alnum:]]|@|-|_|\.)./
如今,如果您将HTML5表单与一起使用,type=email
则由于浏览器引擎具有自己的验证器,因此您已经安全了80%。为了补充它,请将此正则表达式添加到您的正则表达式preg_match_all()
并取反:
if (!preg_match_all("/(?![[:alnum:]]|@|-|_|\.)./",$email)) { .. }
validateEmail
不会是路过的$email
,也不会是路过的$EMAIL
。