PHP如何使用idn_to_ascii作为邮件地址

aydmsdu9  于 2022-12-10  发布在  PHP
关注(0)|答案(3)|浏览(140)

由于在电子邮件地址的本地部分可能有Umlaute(例如öäü),我需要将它们转换为ascii,因为Zend-Mail无法处理它-它总是抛出无效头异常。
所以有一个php函数idn_to_ascii可以将域名转换成IDNA ASCII格式。问题是我不知道如何正确使用它。
让我们以这个电子邮件地址为例:联系我们

// doesn't work (unknown error):
idn_to_ascii('testö@domain.com') --> xn--test@domain-ufb.com

如果我只是转换电子邮件地址的本地部分,它似乎工作:

idn_to_ascii('testö') --> xn--test-8qa@domain.com

但是如果域部分也包含Umlaute呢?
例如testö@domainö.com
我应该这样做吗?

idn_to_ascii('testö').'@'.idn_to_ascii('domainö.com')

在php-homepage上也有人写了一条评论,说你必须跳过高级域部分(官方文档是错误的):请参阅此处

idn_to_ascii('domainö') // right
idn_to_ascii('domainö.com') // wrong

我现在很困惑:|
有人有过这样的经历吗?最糟糕的是:我甚至不能测试它,因为我没有一个电子邮件地址与Umlaute。

ldfqzlk8

ldfqzlk81#

截至2022年12月6日,testö@domain.com不是有效的电子邮件地址,因为本地部分testö)只能包含以下ASCII字符:

  • 大写和小写英语字母(a-z,A-Z)
  • 数字0至9
  • 字符!# $ % & ' * + - / =?^ _'{|} ~
  • 字符(点、句点、句号),前提是该字符不是第一个或最后一个字符,并且不连续出现两次或多次。

参考文献:

  • RFC 3696第3节
  • RFC 822第6.1节
  • 第3.2.3节

RFC 3696第3部分:

确切的规则是任何ASCII字符,包括控制
字符,可能会出现在引号中,或在引号字串中。当引号
则反斜杠字符用于引用以下内容
字符。例如

Abc\@def@example.com

是电子邮件地址的有效格式。也可能出现空格,如

Fred\ Bloggs@example.com

反斜杠字符还可用于引用其自身,例如,

Joe.\\Blow@example.com

除了使用反斜杠字符进行引用外,还可以使用常规的双引号字符将字符串括起来。

"Abc@def"@example.com

  "Fred Bloggs"@example.com

是上述前两个例子的替代形式。这些引用的形式很少被推荐,在实践中也不常见,但是,作为
必须由
处理电子邮件地址。特别是,引用的表单通常
出现在与从
其他系统和环境;这些过渡要求仍然
并且由于接受用户提供的电子邮件地址的系统
无法“知道”该地址是否与传统地址关联
系统,地址表单必须被接受并传送到电子邮件中
环境中。
如果没有引号,本地部分可以由以下内容的任意组合组成
字母字符、数字或任何特殊字符

! # $ % & ' * + - / = ?  ^ _ ` . { | } ~

句点(“.”)也可以出现,但不能用于开始或结束本地部分,也不能出现两个或多个连续的句点。换句话说,除at符号(“@”)、反斜杠、双引号、逗号或方括号之外的任何ASCII图形(打印)字符都可以不加引号出现。如果要出现任何排除字符列表,则必须加引号。诸如

user+mailbox@example.com
ykejflvf

ykejflvf2#

简单一点:

function email_to_ascii($email) {
    $explode = explode('@', $email);
    return $explode[0].'@'.idn_to_ascii($explode[1]);
}
apeeds0o

apeeds0o3#

请尝试以下操作:

function emailToAscii($email) {

    $explodedMail = explode('@', $email);

    $mailName = idn_to_ascii(array_first($explodedMail));

    $mailDomain = last($explodedMail);

    $explodedDomain = explode('.', $mailDomain);

    $secondLvlDomain = idn_to_ascii(array_first($explodedDomain));

    $firstLvlDomain = idn_to_ascii(last($explodedDomain));

    return "$mailName@$secondLvlDomain.$firstLvlDomain";
}

相关问题