我尝试了PHP的内置函数: filter_input()
var_dump(filter_var('john.doe.@gmail.com', FILTER_VALIDATE_EMAIL));
输出:
string(19)“john.doe。@ gmail.com”
然后我尝试了最新版本的Zend Framework(1.11.3):
$validator = new Zend_Validate_EmailAddress();
if ($validator->isValid('john.doe.@gmail.com')) {
echo 'OK';
} else {
foreach ($validator->getMessages() as $message) {
echo "$message\n";
}
}
输出:
'john.doe'。不能与点原子格式匹配
中没有有效的本地部分
'john.doe。'不能与引号字符串格式匹配
'john.doe。'在电子邮件地址'john.doe。@ gmail.com'
内置函数应返回FALSE或Zend方法返回'OK'。
我的中心问题是:
哪一个是对的?
答案 0 :(得分:2)
http://framework.zend.com/manual/en/zend.validate.set.html并没有真正表明他们是否严格遵守RFC,所以让我们来看看源代码。
在源代码中,_validateLocalPart()定义了它们匹配的EBNF:
// Dot-atom characters are: 1*atext *("." 1*atext)
// atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
// "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) {
看起来他们肯定会严格遵守 - 因此本地部分不能以点开头或结尾。
上面的模式与rfc2822规范中的完全相同:http://www.ietf.org/rfc/rfc2822.txt - Zend / Validate / EmailAddress.php中的isValid docblock将其引用为2822。
所以,如果你想要符合rfc2822,那么Zend_Validate_EmailAddress就是正确的,而且filter_input很可能是不符合规范的。
答案 1 :(得分:1)
可能只是Zend_Engine严格匹配RFC(对于电子邮件而言是3英里长)。我怀疑,严格来说,句号是允许的字符,但是不允许在@位置之前的句号,所以这可能是问题所在。
我将假设gmail仍然允许发送john.doe。@ gmail.com。如果是这种情况,问题就变得更多的是你是否真的想要严格匹配RFC,或者只是在允许的电子邮件地址中允许它不会伤害你的系统。
如果你担心sql注入,请在sql&中绑定你的变量。逃避你的HTML,因为不能保证rfc的严格匹配实际上可以防止这样的问题。
如果您担心电子邮件是可发送/可接收的,我建议只是发送预期收据,或使用确认链接设置可选的电子邮件确认系统。
如果您担心电子邮件标题注入,这是在发送邮件时使用电子邮件库的一个很好的理由,我希望zend有一个强大的邮件库。
TooLongDidn'tRead; 我的建议是:
答案 2 :(得分:1)
它还取决于您拥有的PHP版本。 PHP 5.2.14及更高版本(以及5.3)具有更新的正则表达式(请参阅the commit to the PHP source code)。 PHP 5.2.13RC2及更低版本具有旧的正则表达式。另请参阅Bug #49576。