【问题标题】:Why does filter_var($email, FILTER_VALIDATE_EMAIL) allow test@test?为什么 filter_var($email, FILTER_VALIDATE_EMAIL) 允许 test@test?
【发布时间】:2011-03-25 07:17:00
【问题描述】:

我只是为一个表单设置验证,我决定尝试使用 filter_var 函数来检查我的电子邮件地址的有效性。我无法找到 filter_var 实际上在任何地方允许的内容(因为文档非常简单),我发现它允许使用像 test@test 这样的电子邮件地址。域中不是必须有 .com、.net 等吗?

【问题讨论】:

  • 从技术上讲,test 可能是本地网络中的有效主机名,所以我认为它是正确的。
  • 你能发布你的代码吗? var_dump(filter_var('test@test.', FILTER_VALIDATE_EMAIL));为我返回 false !
  • 没有点的test@test也返回false
  • 你可以在这里看到实现:svn.php.net/viewvc/php/php-src/trunk/ext/filter/…
  • filter_var('test@test.de', FILTER_VALIDATE_EMAIL) 无效。行为一定已经改变了。

标签: php email-validation


【解决方案1】:

这种行为在 4 月左右发生了变化。见bug #49576revision 297350

那封电子邮件确实是无效的,或者至少 PHP 开发人员是这样理解的。消息来源携带此通知:

/*
 * The regex below is based on a regex by Michael Rushton.
 * However, it is not identical.  I changed it to only consider routeable
 * addresses as valid.  Michael's regex considers a@b a valid address
 * which conflicts with section 2.3.5 of RFC 5321 which states that:
 *
 *   Only resolvable, fully-qualified domain names (FQDNs) are permitted
 *   when domain names are used in SMTP.  In other words, names that can
 *   be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
 *   in Section 5) are permitted, as are CNAME RRs whose targets can be
 *   resolved, in turn, to MX or address RRs.  Local nicknames or
 *   unqualified names MUST NOT be used.

changelog 提到了这个针对 PHP 5.3.3 和 PHP 5.2.14 的错误修复。

【讨论】:

  • 从 PHP5.3.3 和 PHP5.2.14 开始,该 bug 的票被标记为已修复
  • 非常棒的Artefacto。所以我假设规则已经改变了?为什么这发生了变化?我希望他们能解释他们在 filter_var 文档中检查的内容。那么这会在 5.3.3 之前返回 true 而在 5.3.3 之后返回 false 吗?我使用的系统是 5.2.12
  • @Metro 检查电子邮件是否符合 Internet 标准。 test@test 之前被允许的事实是一个错误。
  • @artefacto 那么在 5.3.3 和 5.2.14 之前的版本中检查这一点的最完整证明方法是什么?
  • @Metropolis 您可以从 rev 297350 中获取 RegEx 模式并将其制成自定义验证器函数,或者直接与 FILTER_VALIDATE_REGEXP 一起使用。
【解决方案2】:

这是一个有效的电子邮件地址。它不能在 Internet 上工作(至少现在不行),但对于本地地址来说没问题。

我认为开发人员正在采取明智的方法来检查电子邮件地址,而不是为自己构建一个保证在引入新 TLD 后就会过时的系统。我们有足够的电子邮件地址语法检查器,可以拒绝foo@example.museum

【讨论】:

  • 您认为 RFC 5321 的第 2.3.5 节不适用吗?
【解决方案3】:

test@test 在语法上是有效的。

来自 RFC 5321:

在电子邮件地址中单独使用顶级域的情况下,使用单个字符串,不带任何点。

只有在这之后才说:

只允许使用可解析的完全限定域名 (FQDN) 在 SMTP 中使用域名时。换句话说,可以 被解析为 MX RR 或地址(即 A 或 AAAA)RR(如所讨论的 在第 5 节中)是允许的,其目标可以是 CNAME RR 依次解析为 MX 或地址 RR。当地昵称或 不得使用不合格的名称。

这并不一定排除仅限 TLD 的域名。其实运行如下代码:

checkdnsrr('ua', 'MX') // Returns true

getmxrr('ua', $array) // 返回真

仅限 TLD 的域名(可以)有 MX 记录并且正在使用http://www.to/ 就是一个例子。以下是一些有效的仅限 TLD 域名的电子邮件地址:

文斯@ai

保罗@io

root@km

joost@tk

管理员@tt

hostmaster@ua

示例电子邮件地址的来源:Tony Finch – TLDs with MXs

【讨论】:

    【解决方案4】:

    不,test 可以是本地/内部网络域,这样就可以了。我喜欢它在开发时正确验证wrikken@localhost

    普通的nonexistentdomain.foo 也会有同样的问题。如果您想测试某个东西是否可以交付给主机,请使用getmxrr(如果失败则回退到gethostbyname())。

    【讨论】:

    • 那么最好允许本地地址吗?或者如果我不想允许像 test@test 这样的东西,我应该使用 getmxrr 吗?
    • 使用 checkdnsrr 检查会不会更好?因为如果他们的服务器宕机或其他原因,那么 getmxrr 将返回 false。对吗?
    • 如果您希望/期望处理本地地址(主要在已知的 IP 范围内),您将允许这些地址。您确实可以使用 checkdnsrr('hostname','ANY'),但我没有想到(尽管检查 MX 或 A 记录(如果没有定义 MX,这应该是后备)会更可靠:注册域可能没有 A 和 MX 记录,导致无法投递)。 checkdnsrr / gethostbyname / getmxrr 都使用相同的机制 afaik,因此,如果 DNS 服务器关闭或运行缓慢,所有选项都会失败/运行缓慢。
    猜你喜欢
    • 2016-03-11
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 2012-09-18
    相关资源
    最近更新 更多