How to validate an email address in PHP
我有这个功能来验证电子邮件地址:
1 2 3 4 5 | function validateEMAIL($EMAIL) { $v ="/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/"; return (bool)preg_match($v, $EMAIL); } |
这可以检查电子邮件地址是否有效吗?
检查电子邮件地址是否格式正确的最简单,最安全的方法是使用
1 2 3 |
此外,您可以检查域是否定义
1 2 3 |
但这仍然不能保证邮件存在。找到答案的唯一方法是发送确认邮件。
现在您可以随时阅读有关电子邮件地址验证的内容,如果您需要学习或者只是使用快速答案并继续前进。别往心里放。
尝试使用正则表达式验证电子邮件地址是一项"不可能"的任务。我甚至会说你所制作的正则表达式毫无用处。有三个rfc关于emailaddresses和写一个正则表达式来捕捉错误的电子邮件,同时没有误报是没有凡人可以做的事情。查看此列表,了解PHP的
即使是内置的PHP函数,电子邮件客户端或服务器也无法做到正确。仍然在大多数情况下
如果您想知道PHP(当前)用于验证电子邮件地址的正则表达式模式,请参阅PHP源代码。
如果您想了解有关电子邮件地址的更多信息,我建议您开始阅读规范,但我必须警告您,这不是一个容易阅读的内容:
- rfc5322
- rfc5321
- rfc3696
- rfc6531(允许unicode字符,尽管许多客户端/服务器不接受它)
请注意,
1 2 3 4 5 6 7 8 9 | <?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 } |
附:关于上面使用的正则表达式模式的注释(来自PHP源代码)。看起来Michael Rushton有一些版权。如上所述:"请随意使用并重新分发此代码。但请保留此版权声明。"
您可以使用filter_var。
1 2 3 4 5 |
根据我的经验,
相反,最好确保地址包含电子邮件地址(用户,"@"符号和域)的所有必需部分,然后验证域本身是否存在。
无法确定(服务器端)是否存在外部域的电子邮件用户。
这是我在Utility类中创建的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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; } |
我认为你可能最好使用PHP的内置过滤器 - 在这种特殊情况下:
当提供
这不仅会验证您的电子邮件,还会针对意外字符进行清理:
1 2 3 4 5 6 7 8 9 | $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); } |
在关于电子邮件验证的"热门问题"中回答了此问题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".
因此,只需检查@,在前端提示用户并在给定地址上发送验证电子邮件。
如果您只是在寻找允许各种点,下划线和短划线的实际正则表达式,则如下所示:
在这里阅读答案之后,这就是我最终的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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; } |
如果您想检查提供的电子邮件地址是否有效,请使用以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * 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) } } |
这是过滤大量无效电子邮件地址以及标准电子邮件验证的便捷方式,因为有效的电子邮件格式并不意味着有效的电子邮件。
请注意,
另请注意,无法验证IPv4或IPv6作为电子邮件中的域部分(例如
在这里查看更多。
1 | /(?![[:alnum:]]|@|-|_|\.)./ |
如今,如果您使用带有
1 |
找到HTML5表单用于验证的正则表达式
https://regex101.com/r/mPEKmy/1