mlocati / idna
国际域名名称(IDNA)2008 库
1.1.2
2023-04-04 16:14 UTC
Requires
- php: >=5.3
Requires (Dev)
- phpunit/phpunit: ^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.5 || ^9.6 || ^10
README
国际域名 PHP 库
介绍与术语
历史上,我们只能使用由ASCII字符组成的域名(例如:www.example.com)。
一种名为国际域名(简称IDN)的新技术允许您使用大多数Unicode字符,例如您可以有www.例.中国
。
为了与所有现有的互联网工作软件保持兼容性,包含非ASCII字符的域名以特殊格式表示,该格式仅使用ASCII字符,称为Punycode。
映射
从IDN生成Punycode应该是不区分大小写的:浏览到www.example.com
应该与浏览到www.Example.COM
相同。
在PHP中,将字符串转换为小写就像调用strtolower
一样简单,但此函数不适用于ASCII字符之外的字符(实际上,它可能会搞乱IDN名称)。如果您有mbstring
PHP扩展,您可能认为可以使用它提供的mb_strtolower
PHP函数。
顺便说一下,即使mb_strtolower
也不是一个好的选择,原因如下
mbstring
PHP扩展可能不可用mb_strtolower
在不同PHP版本中的行为不同(例如,对于PHP 7.0,Ԩ
被正确转换为ԩ
,但旧版本保留了Ԩ
)mb_strtolower
不翻译标准建议的许多Unicode字符
Unicode提供了一个映射表,其中包含了建议的映射(例如,将A
映射到a
,但也将。
映射到。
)。
偏差
有两个标准定义了应用于IDN的映射,即IDNA2003和IDNA2008。IDNA2008与IDNA2003向后兼容,但有一些不兼容的差异。
例如,IDNA2003要求将ß
映射到ss
,而IDNA2008允许使用ß
。因此,较旧的浏览器和客户端软件将www.schloß.com
解析为与www.schloss.com
对应的Punycode,而较新的浏览器将其解析为www.schloß.com
的Punycode。
由于生成的Punycode不同(称为偏差),这导致了重大的安全问题,您需要知道域名发生了偏差。
此库的优点
- 不依赖于任何PHP扩展
- 不依赖于任何其他PHP库
- 在不同PHP版本中保持一致性
- 结果保证遵循标准(它不仅仅是多字节到Punycode转换库)
- 设计时考虑速度
- 与从PHP 5.3到最新PHP版本(写作时的8.2)的任何PHP版本兼容
示例用法
require_once 'autoload.php'; // Not required if you use composer $domain = \MLocati\IDNA\DomainName::fromName('www。schloß.COM'); echo "Name: ", $domain->getName(), "\n"; echo "Punycode: ", $domain->getPunycode(), "\n"; echo "Deviated: ", $domain->isDeviated() ? 'yes' : 'no', "\n"; echo "Deviated Name: ", $domain->getDeviatedName(), "\n"; echo "Deviated Punycode: ", $domain->getDeviatedPunycode(), "\n";
输出
Name: www.schloß.com
Punycode: www.xn--schlo-pqa.com
Deviated: yes
Deviated Name: www.schloss.com
Deviated Punycode: www.schloss.com