'PHP how to use idn_to_ascii for mail adresses

since it's possible to have Umlaute (e.g. öäü) in the local part of an email address I need to convert them to ascii because Zend-Mail is not able to handle it - it always throws invalid header exception.

So there is this php-function idn_to_ascii which converts domain names to IDNA ASCII format. The problem is that I'm not sure how to use it correctly.

Let's take this email address: testö@domain.com

// doesn't work (unknown error):
idn_to_ascii('testö@domain.com') --> [email protected]

If I just convert the local part of the email address it seems to work:

idn_to_ascii('testö') --> [email protected]

But what if also the domain part contains Umlaute?
e.g. testö@domainö.com

should I do something like this?

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

Also on the php-homepage someone wrote a comment that you have to skip the high-level domain part (and the official documentation is wrong): see here

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

I'm so confused now :|
Someone has experience in that? And the worst thing is: I can't even test it because I don't have an email address with Umlaute.



Solution 1:[1]

As of 26 April 2017, testö@domain.comis invalid because the local part (testö) of an email address may use any of these ASCII characters:

  • Uppercase and lowercase English letters (a-z, A-Z)
  • Digits 0 to 9
  • Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • Character . (dot, period, full stop) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively.

RFC 5322 Section 3.2.3

Solution 2:[2]

Try something like this:

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";
}

Solution 3:[3]

Something a bit more simple:

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ???? ????????
Solution 3