我正在用 php 编写一个网站,我目前在联系我们页面上,我想知道验证电子邮件地址的最佳方法是什么?
- 通过向他们的电子邮件发送验证链接?
- 正则表达式
- 还有什么方法吗?
你能告诉我为什么和我实现它的指南吗?我不希望有人为我编写代码,因为这对我来说没有乐趣,我不会学习,而只是对用于实现上述任一方法的技术的一些指导。
我还将使用这些方法在我的网页上实现订阅按钮。这是最好的方法吗?我应该考虑其他任何方法吗?
我正在用 php 编写一个网站,我目前在联系我们页面上,我想知道验证电子邮件地址的最佳方法是什么?
你能告诉我为什么和我实现它的指南吗?我不希望有人为我编写代码,因为这对我来说没有乐趣,我不会学习,而只是对用于实现上述任一方法的技术的一些指导。
我还将使用这些方法在我的网页上实现订阅按钮。这是最好的方法吗?我应该考虑其他任何方法吗?
我通常会通过这些步骤
如果第一步失败,它永远不会到达第二步。如果由于电子邮件不存在而导致电子邮件发送失败,我会删除该帐户或做一些其他事情
- 编辑
3 - 如果由于某种原因未发送激活电子邮件、未删除电子邮件、未批准 7 天(或根据您的配置),则在这些天之后每 2-3 小时尝试重新发送电子邮件如果不成功,则删除电子邮件
4 - 如果电子邮件发送成功但未激活,它将保持未批准状态,但可以通过生成新的激活码随时重新激活
我认为最好的是 3. 和 1 的组合。
在初始阶段,您从语法上验证电子邮件(以捕捉拼写错误):
filter_var($email, FILTER_VALIDATE_EMAIL)
在第二个中,您发送一封带有确认地址的电子邮件(以捕获错误和故意错误的信息)。
最好的方法是发送一封包含验证链接的电子邮件。至少如果您不想要激活电子邮件,请验证电子邮件地址。最好的电子邮件验证功能是Dominic Sayers 的符合 RFC 的电子邮件地址验证器。
只需在项目中包含 php 文件并像这样使用它:
if (is_email($email, $checkDNS, $diagnose)) //$checkDNS and $diagnose are false by default
echo 'Email valid';
else
echo 'Email invalid';
这取决于用户是否真的想收到回复。
如果用户提出问题,他会希望得到答复,并且可能会提供他的有效电子邮件地址。在这种情况下,我会使用非常松散的正则表达式检查来发现拼写错误或丢失的地址。(有点像.+@.+
。)
如果用户不想被联系,但您想知道他们的地址,则需要使用验证链接。没有其他方法可以确保电子邮件地址有效且属于用户。
正则表达式并不真正适合确定电子邮件地址语法的有效性,并且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
在发送验证电子邮件之前,您还可以使用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 上不可用。
取决于你的目标。如果您必须拥有有效且有效的电子邮件,那么您必须发送一封需要验证收据的电子邮件。在这种情况下,除了为您的用户提供方便外,不需要正则表达式验证。
但是,如果您希望帮助用户避免拼写错误,同时尽量减少用户的烦恼,请使用正则表达式进行验证。
这里有一些很好的答案,除了正则表达式位外,我同意所选的答案。正如其他人指出的那样,即使不是不可能,也很难找到一个完全实现 RFC 5321 的所有怪癖的正则表达式。
欢迎您使用我的免费 PHP 函数is_email()
来验证地址。它在这里可用。
它将确保地址完全符合 RFC 5321。它还可以选择检查域是否实际存在。
您不应该依赖验证器来告诉您用户的电子邮件地址是否确实存在:一些 ISP 会向其用户提供不合规的地址,尤其是在不使用拉丁字母的国家/地区。更多关于电子邮件验证的文章在这里:http: //isemail.info/about。
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;