如何在PHP中validation电子邮件地址

我有这个函数来validation电子邮件地址:

function validateEMAIL($EMAIL) { $v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/"; return (bool)preg_match($v, $EMAIL); } 

这是否可以检查电子邮件地址是否有效?

检查电子邮件地址是否合适的最简单和最安全的方法是使用filter_var()函数:

 if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // invalid emailaddress } 

另外,您可以检查域是否定义了MXlogging:

 if (!checkdnsrr($domain, 'MX')) { // domain is not valid } 

但是这仍然不能保证邮件的存在。 唯一的办法是发送确认邮件。


现在,您可以轻松地阅读关于电子邮件地址validation的简单答案,如果您想学习或使用快速答案并继续前进。 别往心里放。

尝试使用正则expression式validation电子邮件地址是一个“不可能”的任务。 我会尽可能地说,你所做的正则expression式是无用的。 关于电子邮件地址有三个rfc,写一个正则expression式来抓错误的电子邮件地址,同时也没有误报是不可能的。 查看PHP的filter_var()函数使用的正则expression式的testing(失败和成功) 列表 。

即使内置的PHP函数,电子邮件客户端或服务器也不对。 仍然在大多数情况下filter_var是最好的select。

如果你想知道PHP(当前)使用哪个正则expression式模式来validation电子邮件地址,请参阅PHP源代码 。

如果你想了解更多关于电子邮件地址的信息,我build议你开始阅读规范,但是我必须警告你,这不是一个简单的方法:

  • rfc5322
  • rfc5321
  • rfc3696
  • rfc6531 (允许unicode字符,虽然许多客户端/服务器不接受它)

请注意filter_var()和前面已经提到的一样,只能在PHP 5.2中使用。 如果您希望它能够使用早期版本的PHP,则可以使用PHP中使用的正则expression式:

 <?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,}(?:(?:[az][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上面使用的正则expression式模式的注释(来自PHP源代码)。 看起来好像Michael Rushton有一些版权。 如上所述:“请随意使用并重新发布此代码,但请保留此版权声明。

你可以使用filter_var 。

 <?php function validateEmail($email) { return filter_var($email, FILTER_VALIDATE_EMAIL); } ?> 

我想你可能会更好使用PHP的内置filter – 在这种情况下:

当使用FILTER_VALIDATE_EMAIL参数提供时,它可以返回true或false。

根据我的经验, regex解决scheme有太多的误报,而filter_var()解决scheme有错误的反面(尤其是所有新的TLD )。

相反,最好确保地址具有电子邮件地址(用户,“@”符号和域)的所有必需部分,然后validation域本身是否存在。

没有办法确定(服务器端)是否存在外部域的电子邮件用户。

这是我在Utility类中创build的一个方法:

 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; } 

这不仅会validation您的电子邮件,还会为意外字符消毒:

 $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); } 

在关于电子邮件validation的“顶级问题”中回答了这个问题https://stackoverflow.com/a/41129750/1848217

对我来说,检查电子邮件的正确方法是:

  1. 检查符号@是否存在,前后有一些非@符号: /^[^@]+@[^@]+$/
  2. 尝试发送电子邮件到这个地址与一些“激活码”。
  3. 当用户“激活”他的电子邮件地址时,我们会看到一切正确。

当然,当用户input“陌生”的电子邮件来帮助他避免常见的错误时,例如域名中没有点或没有引号的空格等,您可以在前端显示一些警告或工具提示。 但是如果用户真的需要,你必须接受地址“hello @ world”。

此外,你必须记住,电子邮件地址标准是和可以演变的,所以你不能一次只input一些“标准有效”的正则expression式。 而且你必须记住,一些具体的互联网服务器可能会破坏一些通用标准的细节,实际上它们是用自己的“修改标准”来工作的

所以,只要检查@,在前端提示用户并发送给定地址的validation邮件。

如果你只是寻找一个实际的正则expression式,允许不同的点,下划线和破折号,如下所示: [a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+ 。 这将允许像tom_anderson.1-neo@my-mail_matrix.com这样相当愚蠢的电子邮件进行validation。

 /(?![[:alnum:]]|@|-|_|\.)./ 

如今,如果您使用type=email的HTML5表单,那么由于浏览器引擎具有自己的validation器,因此您已经安全了80%。 为了补充它,添加这个正则expression式到你的preg_match_all()并取消它:

 if (!preg_match_all("/(?![[:alnum:]]|@|-|_|\.)./",$email)) { .. } 

findHTML5表单用于validation的正则expression式
https://regex101.com/r/mPEKmy/1