PHP头条
热点:

必要条件

IETF文档,RFC 1035“域实现和规格说明”,RFC 2234“语法说明书的扩充BNF:ABNF”,RFC 2821“简单邮件传输协议”,RFC 2822“Internet消息格式”,此外还有RFC 3696前面已经引用过),这些文档都包括了email地址验证的信息,RFC 2822取代了RFC 822“标准ARPA Internet文本消息”,并使其过时。

下面列出了一个有效email地址的必要条件,并列出了引用的相关文档:

1、一个email地址是有本地部分和域两部分组成的,以@作为它们之间的分界线。RFC 2822 3.4.1)

2、本地部分是有字母和数字以及!, #, $, %, &, ', *, +, -, /, =, ?, ^, _, `, {, |, }和~字符组成的,可能在其内部使用.)作为分隔符,但不能用在开始、结尾或另一个.)后面。RFC 2822 3.2.4)

3、本地部分可能包括引用字符串,也就是说,在")内,可以使用任何字符,包括空格。RFC 2822 3.2.5)

4、在本地部分还可以包含引用对如\@),尽管这个定义来自一个过时的RFC 822文档。RFC 2822 4.4)

5、本地部分字符长最大长度是64个字符。RFC 2821 4.5.3.1)

6、域部分是通过.)分隔的标记组成的。RFC1035 2.3.1)

7、域部分是以字母开头的,后面跟0、字母、数字或连字符-),以字母或数字字符结尾。RFC 1035 2.3.1)

8、一个域标记的最大字符长度为63。RFC 1035 2.3.1)

9、整个域部分的最大字符长度为255。RFC 2821 4.5.3.1)

10、域必须具有完全合格的,可解析的DNS A记录和MX记录。RFC 2821 3.6)

必要条件编号4包括一个过时的引用,但它是经过论证可以使用的,代理商很可能会屏蔽掉这类地址,但对于现有的这类地址,它们仍然是合法的。

标准采用的是七位字符编码,而不是多位字符,因此,按照RFC 2234的定义,字母要符合Latin字母范围a-z和A-Z,同样,数字指的是0-9,国际标准Unicode字母是不被接受的,即使是以UTF-8进行编码也不行,ASCII码仍然是统治地位。

开发一个更好的email校验器

必要条件实在是太多了!它们中绝大多数都涉及到本地部分和域部分,其中2-5应用到本地部分,6-10应用于域部分。

在本地名称部分还是可以使用@字符的,如Abc\@def@example.com和"Abc@def"@example.com,这就意味着以@标记作为分水岭是一个错误,$split = explode("@", $email);与此类似的技巧也是不行的,我们可以尝试移除@标记,$cleanat = str_replace("\\@", "");,但这样又会错过一些病例,如Abc\\@example.com,幸运的是,在域部分是不运行以@标记作为分水岭的,最后一个@字符必须明确为分隔符,这种分隔本地部分和域部分的方法使用了strrpos函数在email字符串中查找最后一个@字符。

清单3提供了一个更好的分隔email字符串本地和域部分的方法,如果在email字符串中strrpos函数没有找到@字符,就返回一个布尔值false。

清单3:分裂本地部分和域部分

$isValid = true;
$atIndex = strrpos($email, "@");
if (is_bool($atIndex) && !$atIndex)
{
   $isValid = false;
}
else
{
   $domain = substr($email, $atIndex+1);
   $local = substr($email, 0, $atIndex);
   // 域和本地部分一起
}

让我们从简单的开始说起,检查本地部分和域部分的长度非常简单,如果这些测试都失败了,就不用再做更多的测试,清单4显示了测试长度的代码。

清单4:本地部分和域部分长度测试

$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen < 1 || $localLen > 64)
{
   // 本地部分长度超出
   $isValid = false;
}
else if ($domainLen < 1 || $domainLen > 255)
{
   //域部分长度超出
   $isValid = false;
}

现在,本地部分有一到两种格式,它可能以嵌入式引用开始或结束,Doug \"Ace\" L.就是一个本地部分的示例,本地部分的另一种格式是(a+(\.a+)*),它使用了大量的标准字符,第二种比第一种更常见,因此要首先检查它,未引用格式失败后请寻求引用格式。

引用字符时使用反斜杠\@),这种格式允许使用两个反斜杠来在结果中获得一个反斜杠字符\\),这就意味着我们还得为没有反斜杠的字符串检查反斜杠的数量可能为奇数,我们需要允\\\\\@,拒绝\\\\@。

写一个正则表达式查找在非反斜杠字符前的字符串中反斜杠的奇数值还是可以实现的,虽然可以实现,但并不完美,实际上在PHP和正则表达式中,反斜杠是一个转义字符,在PHP中我们需要写四个反斜杠字符代表正则表达式显示一个单一的反斜杠。

另一个动人的解决方案是在开始检查之前简单地将测试字符串中的反斜杠字符对剥离出去,这里使用了str_replace函数,清单5显示了一个本地部分内容的测试代码。


www.phpzy.comtrue/php/19078.htmlTechArticle必要条件 IETF文档,RFC 1035“域实现和规格说明”,RFC 2234“语法说明书的扩充BNF:ABNF”,RFC 2821“简单邮件传输协议”,RFC 2822“Internet消息格式”,此外还...

相关文章

PHP之友评论

今天推荐