如何在PHP中验证电子邮件地址

Cam*_*ron 205 php regex email email-validation

我有这个功能来验证电子邮件地址:

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

    return (bool)preg_match($v, $EMAIL);
}
Run Code Online (Sandbox Code Playgroud)

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

Pee*_*Haa 536

检查电子邮件地址是否格式正确的最简单,最安全的方法是使用以下filter_var()功能:

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // invalid emailaddress
}
Run Code Online (Sandbox Code Playgroud)

此外,您可以检查域是否定义MX记录:

if (!checkdnsrr($domain, 'MX')) {
    // domain is not valid
}
Run Code Online (Sandbox Code Playgroud)

但这仍然不能保证邮件存在.找到答案的唯一方法是发送确认邮件.


现在您可以随时阅读有关电子邮件地址验证的内容,如果您需要学习或者只是使用快速答案并继续前进.别往心里放.

尝试使用正则表达式验证电子邮件地址是一项"不可能"的任务.我甚至会说你所制作的正则表达式毫无用处.有三个rfc关于emailaddresses和写一个正则表达式来捕捉错误的电子邮件,同时没有误报是没有凡人可以做的事情.查看此列表,了解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
}
Run Code Online (Sandbox Code Playgroud)

PS关于上面使用的正则表达式模式的注释(来自PHP源代码).看起来Michael Rushton有一些版权.如上所述:"请随意使用并重新分发此代码.但请保留此版权声明."

  • 不,对该模式的测试失败太多https://emailtester.pieterhordijk.com/test-pattern/MTAz :-) (4认同)
  • @PeeHaa:Postfix 3.0支持它近两年了:http://www.postfix.org/SMTPUTF8_README.html,它包含在Ubuntu 16.04中,并将包含在下一个Debian版本中,例如.Exim有实验支持.Gmail之类的网络邮件提供商也增加了对发送/接收此类电子邮件的支持,但您还无法创建unicode帐户.广泛的使用和支持是可以实现的,并且`filter_var`将落后很长一段时间,即使他们现在改变它(我已经发布了一个错误报告). (4认同)
  • 它不适用于*all*emailaddresses,如上所述.另请参阅我的答案中的失败测试列表,以查看某些引用的字符串是否有效而其他字符串不起作用. (3认同)
  • XSS 预防与此答案无关。 (2认同)

Cam*_*tin 39

您可以使用filter_var.

<?php
   function validateEmail($email) {
      return filter_var($email, FILTER_VALIDATE_EMAIL);
   }
?>
Run Code Online (Sandbox Code Playgroud)

  • @user2607743我认为这是有道理的,如果你一年后在你的项目中使用它100次并且你想改进验证电子邮件的方式......那么编辑1个函数会比编辑100个函数更快地方。 (7认同)
  • 所有包含一行函数的一行函数是怎么回事?我到处都看到他们。这什么时候变成“事”了?(修辞)。这需要停止。 (4认同)
  • 停止添加此功能,因为这不会验证域。如果您添加一些@地址,这是有效的。事实并非如此! (2认同)
  • @HerrNentu' some@address 有什么问题吗?这是一个完全有效的电子邮件地址。就像 root@localhost 就是其中之一。你只是做错了事。您正在语法上验证电子邮件地址的形式,并且根据 RFC,some@address 是有效的。但您想要做的是验证地址是否可达。仅当主机“地址”在您的网络中已知时,某些@地址才可访问。要验证可达性,您可以检查 DNS(检查主机是否存在)或使用 SMTP(检查邮箱是否存在)。 (2认同)

Jab*_*ari 13

根据我的经验,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;
}
Run Code Online (Sandbox Code Playgroud)


Flu*_*feh 9

我认为你可能最好使用PHP的内置过滤器 - 在这种特殊情况下:

当与FILTER_VALIDATE_EMAILparam一起提供时,它可以返回true或false .


小智 8

这不仅会验证您的电子邮件,还会针对意外字符进行清理:

$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);
}
Run Code Online (Sandbox Code Playgroud)


Fla*_*orm 5

在关于电子邮件验证的“热门问题”中回答了这个问题/sf/answers/2879082531/

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

  1. 检查符号@ 是否存在,并且在它前后有一些非@ 符号: /^[^@]+@[^@]+$/
  2. 尝试向此地址发送一封带有一些“激活码”的电子邮件。
  3. 当用户“激活”他的电子邮件地址时,我们将看到一切正常。

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

此外,您必须记住电子邮件地址标准曾经并且可以演变,因此您不能一劳永逸地键入一些“标准有效”的正则表达式。并且您必须记住,某些具体的 Internet 服务器可能无法满足通用标准的某些细节,并且实际上可以使用自己的“修改后的标准”。

因此,只需检查@,在前端提示用户并在给定地址上发送验证电子邮件。


Pel*_*red 5

在阅读了这里的答案后,这就是我的结论:

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;
}
Run Code Online (Sandbox Code Playgroud)


Mos*_*ade 5

使用以下代码:

// Variable to check
$email = "john.doe@example.com";

// Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);


// Validate e-mail
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
  echo("Email is a valid email address");
}
Run Code Online (Sandbox Code Playgroud)

  • 在大多数情况下,您可能不想在验证时删除这样的非法字符。如果您检查的电子邮件地址包含非法字符,则不应验证该地址。 (2认同)

归档时间:

查看次数:

285306 次

最近记录:

6 年,1 月 前