Php 我应该使用filter_var验证电子邮件吗?
我有一个类,它在我将每个输入发送到数据库层之前验证它。请注意,我的问题不是逃跑什么的。我的数据库层将处理SQL注入问题。我想做的就是验证电子邮件是否有效,因为稍后该电子邮件可能会用作“发送到”。例如,用户将通过发送到电子邮件的链接恢复对其帐户的访问。我读了很多关于过滤变量的书,有一大群人反对,另一大群人赞成。将重点放在“我只是想验证电子邮件,而不是对其进行数据库、html或XSS等过滤”,使用Php 我应该使用filter_var验证电子邮件吗?,php,validation,Php,Validation,我有一个类,它在我将每个输入发送到数据库层之前验证它。请注意,我的问题不是逃跑什么的。我的数据库层将处理SQL注入问题。我想做的就是验证电子邮件是否有效,因为稍后该电子邮件可能会用作“发送到”。例如,用户将通过发送到电子邮件的链接恢复对其帐户的访问。我读了很多关于过滤变量的书,有一大群人反对,另一大群人赞成。将重点放在“我只是想验证电子邮件,而不是对其进行数据库、html或XSS等过滤”,使用filter\u var是否有问题?是的,您应该使用filter\u var,这就是您可以合并它的方式:
filter\u var
是否有问题?是的,您应该使用filter\u var
,这就是您可以合并它的方式:
if( filter_var( $email ,FILTER_VALIDATE_EMAIL ) )
{
/*
* Rest of your code
*/
}
是的,你应该
使用标准库验证而不是自制验证有多种好处:
checkdnsr()
在这里也值得一提
filter\u var()
将批准似乎不完整的域,因为它可能在本地上下文中有效(例如。someone@localhost). 这可能导致误报,人们只是错过了域名中的TLD或点(例如hattie)。jacques@gmailcom)
通过在域上查找来捕获这些信息-如果您可以找到域的MX记录并且地址有效,那么您已经尽了最大努力
示例代码:
if(filter_var($email, FILTER_VALIDATE_EMAIL))
{
list($userName, $mailDomain) = explode("@", $email);
if (!checkdnsrr($mailDomain, "MX"))
{
// Email is unreachable.
}
}
else
{
// Email is bad.
}
checkdnsr()
是非常即时的(以我的经验),我还没有找到一个它不工作的环境。不幸的是,filter\u var
在地址的本地部分(在@之前)不支持UTF8,为了支持国际域名,您需要分别通过idn\u to\u ascii
运行域名(这很麻烦,也不明显)
这使得filter\u var
在我看来毫无用处:在野外出现的unicode电子邮件地址越多,合法的电子邮件地址就越会失败,尤其是像中国或巴西这样对这些地址有明显需求的国家filter\u var
也不允许像root@localhost
,在服务器环境中有效且可能有用
如果存在一个电子邮件库来根据特定的说明进行验证,这将非常有用-是否只允许使用域名,或者是否也允许使用任意主机(如localhost),或者是否有一个自定义域的白名单,该白名单应该是有效的?应该允许使用unicode吗?免费邮件域名(如@homail.com)有哪些常见的打字错误也会失败
此外,以更具体的方式验证某些域名是明智的——hotmail.com目前不允许使用unicode字符,并且对可用字符有特定的限制。由于PHP应用程序中大多数使用的电子邮件地址都集中在大约100个不同的域上,因此可以用这种方法更好地验证这些域名。不幸的是,据我所知,目前还没有这样的库。我看到的一些评论与我的测试不匹配,因此我想指出我在PHP5.x中发现的功能。如果您首先清理电子邮件,它将删除所有您不想要的字符,然后您可以验证。我有两个功能,以防有人只想做其中一个 检查电子邮件是否有效:
function isValidEmailAddress($email = '', $check_domain = false)
{
if (empty($email)) {
return false;
} else {
$success = true;
}
if (!filter_var((string) $email, FILTER_VALIDATE_EMAIL)) {
$success = false;
}
if ($check_domain && $success) {
list($name, $domain) = explode('@', trim($email) . "@");
if (!checkdnsrr($domain, 'MX')) {
$success = false;
}
}
return array("success" => $success, "email" => $email);
}
拆卸和安装UTF8等:
function sanitizeEmailAddress($email = '') {
if (!empty($email)) {
$email = filter_var(strtolower(trim($email)), FILTER_SANITIZE_EMAIL);
}
return $email;
}
示例用法:
// test --
$list = array('goodÂ@bad.com', 'mikeq@google.com', 'puser@porsche.us', 'quick@us', '', '<yo@marist.edu>', 'hello@us.edu', 'rgil@yahoo.com', 'abc@2r.edu', 'one2@e3.edu', 'key@gen.us');
foreach($list as $email) {
$ret = isValidEmailAddress( sanitizeEmailAddress($email), false );
if ($ret['success']) {
echo "GOOD " . $ret['email'];
} else {
echo "BAD " .$email;
}
echo "\n";
}
如果使用域选项:$ret=isValidEmailAddress(sanitizeEmailAddress($email),true)
<强> 2021,No.<强> >代码> FieldValue/Cuth>的验证实现(如PHP 8)不验证国际域名,我认为这是足够大的理由放弃。< /P> Symfony自己也使用不支持UTF-8的正则表达式
使用。它遵循电子邮件RFC,还可以检查MX记录,以进一步验证该域是否存在。如果您想确保电子邮件格式正确,可以这样做。如果你想知道它是否是一个真实的电子邮件地址,那么你很可能需要支付电子邮件验证服务的费用。你不需要支付验证服务的费用。只需发送一封带有验证链接的电子邮件。是的,你一定要使用
filter\u var
来检查这是否是一个有效的电子邮件地址,因为这是PHP中唯一可靠的检查电子邮件地址的方法…我会在有时间时进行检查,但是我可以马上向你保证,你提到的@gmailcom的例子没有得到filter\u var.True的验证。这本身就是一个问题,尽管只是在相当模糊的情况下。有一个列表列出了过滤、验证和电子邮件的失败;执行checkdnsrr()将捕获代码板示例中给出的所有误报。请注意,checkdnsrr的超时时间为20秒,这显然是无法更改的(一些域的响应方式使其达到20秒,正如我在应用程序中所经历的那样),域名应通过idn_to_ascii()处理
首先支持具有特殊字符的域(如ö、é等)。我切换到使用passthru
调用dig
,这样我就可以指定超时时间和要使用的名称服务器。filter\u var
在这样的电子邮件地址上失败someone@localhost-即使在某些情况下这是一个有效的电子邮件地址。不幸的是,只有当有人真的维护并进一步改进了这样一个系统时,这才是正确的
GOOD good@bad.com
GOOD mikeq@google.com
GOOD puser@porsche.us
BAD quick@us
BAD
GOOD yo@marist.edu
GOOD hello@us.edu
GOOD rgil@yahoo.com
GOOD abc@2r.edu
GOOD one2@e3.edu
GOOD key@gen.us
GOOD good@bad.com
GOOD mikeq@google.com
GOOD puser@porsche.us
BAD quick@us
BAD
GOOD yo@marist.edu
GOOD hello@us.edu
GOOD rgil@yahoo.com
BAD abc@2r.edu
BAD one2@e3.edu
BAD key@gen.us