6

我正在用 php 编写一个网站,我目前在联系我们页面上,我想知道验证电子邮件地址的最佳方法是什么?

  1. 通过向他们的电子邮件发送验证链接?
  2. 正则表达式
  3. 还有什么方法吗?

你能告诉我为什么和我实现它的指南吗?我不希望有人为我编写代码,因为这对我来说没有乐趣,我不会学习,而只是对用于实现上述任一方法的技术的一些指导。

我还将使用这些方法在我的网页上实现订阅按钮。这是最好的方法吗?我应该考虑其他任何方法吗?

4

10 回答 10

16

我通常会通过这些步骤

  1. 正则表达式
  2. 向邮箱发送激活码

如果第一步失败,它永远不会到达第二步。如果由于电子邮件不存在而导致电子邮件发送失败,我会删除该帐户或做一些其他事情

- 编辑

3 - 如果由于某种原因未发送激活电子邮件、未删除电子邮件、未批准 7 天(或根据您的配置),则在这些天之后每 2-3 小时尝试重新发送电子邮件如果不成功,则删除电子邮件

4 - 如果电子邮件发送成功但未激活,它将保持未批准状态,但可以通过生成新的激活码随时重新激活

于 2010-07-15T07:57:19.913 回答
11

我认为最好的是 3. 和 1 的组合。

在初始阶段,您从语法上验证电子邮件(以捕捉拼写错误):

filter_var($email, FILTER_VALIDATE_EMAIL)

在第二个中,您发送一封带有确认地址的电子邮件(以捕获错误和故意错误的信息)。

于 2010-07-15T07:58:12.353 回答
4

最好的方法是发送一封包含验证链接的电子邮件。至少如果您不想要激活电子邮件,请验证电子邮件地址。最好的电子邮件验证功能是Dominic Sayers 的符合 RFC 的电子邮件地址验证器

只需在项目中包含 php 文件并像这样使用它:

if (is_email($email, $checkDNS, $diagnose)) //$checkDNS and $diagnose are false by default
    echo 'Email valid';
else
    echo 'Email invalid';
  • 如果 $checkDNS 设置为 true,它将验证域是否存在。如果域不存在,即使电子邮件有效,该函数也会返回 false。
  • 如果 $diagnose 设置为 true,则该函数返回一个代码而不是布尔值,它会告诉您为什么电子邮件无效(如果有效,则返回 0)。
于 2010-07-15T14:03:01.797 回答
3

这取决于用户是否真的想收到回复。

如果用户提出问题,他会希望得到答复,并且可能会提供他的有效电子邮件地址。在这种情况下,我会使用非常松散的正则表达式检查来发现拼写错误或丢失的地址。(有点像.+@.+。)

如果用户不想被联系,但您想知道他们的地址,则需要使用验证链接。没有其他方法可以确保电子邮件地址有效且属于用户。

于 2010-07-15T07:57:58.750 回答
3

真正知道电子邮件是否有效的唯一方法是向其发送电子邮件。如果您确实需要,请使用其中之一从技术上讲,本地域的 @ 之后甚至不必有任何句点。所需要的只是一个域跟随@。

于 2010-07-15T08:07:13.190 回答
2

正则表达式并不真正适合确定电子邮件地址语法的有效性,并且FILTER_VALIDATE_EMAIL该函数的选项filter_var也相当不可靠。我使用EmailAddressValidator 类来测试电子邮件地址的语法。

我汇总了一些由filter_var(PHP 版本 5.3.2-1ubuntu4.2)返回的错误结果的示例。可能还有更多。有些确实有点极端,但仍然值得注意:

RFC 1035 2.3.1。首选名称语法
http://tools.ietf.org/search/rfc1035
总结为:域由由点分隔符分隔的标签组成(但对于本地域不一定如此)。

echo filter_var('name@example', FILTER_VALIDATE_EMAIL);
// name@example

RFC 1035 2.3.1。首选名称语法
标签必须遵循 ARPANET 主机名的规则。它们必须以字母开头,并且以字母或数字开头,内部字符只能是字母、数字和连字符。

echo filter_var('name@1example.com', FILTER_VALIDATE_EMAIL);
// name@1example

RFC 2822 3.2.5。引用的字符串
https://www.rfc-editor.org/rfc/rfc2822#section-3.2.5
这是有效的(尽管它被许多邮件服务器拒绝):

echo filter_var('name"quoted"string@example', FILTER_VALIDATE_EMAIL);
// FALSE

RFC 5321 4.5.3.1.1。本地部分
https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.1
用户名或其他本地部分的最大总长度为 64 个八位字节。
测试 70 个字符:

echo filter_var('AbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghij@example.com', FILTER_VALIDATE_EMAIL);
// AbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghij@example.com

RFC 5321 4.5.3.1.2。域
https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.2
域名或号码的最大总长度为 255 个八位字节。
测试 260 个字符:

echo filter_var('name@AbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghij.com', FILTER_VALIDATE_EMAIL);
// name@AbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghijAbcdefghij.com

查看Validate an E-Mail Address with PHP, the Right Way了解更多信息。

于 2010-07-15T08:46:10.747 回答
2

在发送验证电子邮件之前,您还可以使用checkdnsrr()来验证域是否存在并且是否设置了 MX 记录。这将检测使用虚假域(如 user@idontexist.com)的电子邮件。

function validateEmail($email, $field, $msg = '')
{
    if (!filter_var($email, FILTER_VALIDATE_EMAIL))
    {
        return false;
    }
    list($user, $domain) = explode('@', $email);
    if (function_exists('checkdnsrr') && !checkdnsrr($domain, 'MX'))
    {
        return false;
    }
    return true;
}

我们需要使用function_exists()来验证我们是否可以使用checkdnsrr()它,因为它在 PHP 5.3 之前的 Windows 上不可用。

于 2010-07-15T13:44:56.843 回答
1

取决于你的目标。如果您必须拥有有效且有效的电子邮件,那么您必须发送一封需要验证收据的电子邮件。在这种情况下,除了为您的用户提供方便外,不需要正则表达式验证。

但是,如果您希望帮助用户避免拼写错误,同时尽量减少用户的烦恼,请使用正则表达式进行验证。

于 2010-07-15T08:16:02.847 回答
0

这里有一些很好的答案,除了正则表达式位外,我同意所选的答案。正如其他人指出的那样,即使不是不可能,也很难找到一个完全实现 RFC 5321 的所有怪癖的正则表达式。

欢迎您使用我的免费 PHP 函数is_email()来验证地址。它在这里可用。

它将确保地址完全符合 RFC 5321。它还可以选择检查域是否实际存在。

您不应该依赖验证器来告诉您用户的电子邮件地址是否确实存在:一些 ISP 会向其用户提供不合规的地址,尤其是在不使用拉丁字母的国家/地区。更多关于电子邮件验证的文章在这里:http: //isemail.info/about

于 2011-03-15T11:22:13.193 回答
-1
 function checkEmail($email) {
  if(preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])
  ↪*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/",
               $email)){
    list($username,$domain)=split('@',$email);
    if(!checkdnsrr($domain,'MX')) {
      return false;
    }
    return true;
  }
  return false;
于 2010-07-15T07:58:18.803 回答