PHP 8.3.27 Released!

idn_to_ascii

(PHP 5 >= 5.3.0, PHP 7, PHP 8, PECL intl >= 1.0.2, PECL idn >= 0.1)

idn_to_asciiПреобразовывает доменное имя в формат ASCII по спецификации IDNA

Описание

Процедурный стиль

idn_to_ascii(
    string $domain,
    int $flags = IDNA_DEFAULT,
    int $variant = INTL_IDNA_VARIANT_UTS46,
    array &$idna_info = null
): string|false

Функция преобразовывает доменные имена в кодировке Юникод в формат, совместимый со стандартом ASCII, и возвращает результат в нижнем регистре. Доменные имена, в состав которых входят символы национальных алфавитов, обрабатываются по правилам механизма интернационализации доменных имён в приложениях — IDNA (англ. Internationalizing Domain Names in Applications).

Список параметров

domain

Домен с символами в кодировке UTF-8, которые требуется преобразовать.

flags

Опции преобразования — комбинация констант семейства IDNA_*, кроме констант семейства IDNA_ERROR_*.

variant

Константа INTL_IDNA_VARIANT_2003 (устарела с PHP 7.2.0) для преобразования домена по правилам спецификации IDNA 2003 или константа INTL_IDNA_VARIANT_UTS46 (доступна только с ICU 4.6) для преобразования по правилам спецификации UTS #46.

idna_info

Параметр влияет на результат только при передаче константы INTL_IDNA_VARIANT_UTS46 в параметр variant. Функция заполнит переменную массивом с ключами 'result' — домен в ASCII-формате, возможно, с ошибками преобразования, 'isTransitionalDifferent' — логическое значение, которое указывает, повлиял ли переходный механизм протокола UTS #46 на результат или мог бы повлиять, и 'errors' — значение int, которое представляет битовую маску из констант семейства IDNA_ERROR_*.

Возвращаемые значения

Функция возвращает доменное имя, закодированное в формате, совместимом со стандартом ASCII, или false, если возникла ошибка.

Список изменений

Версия Описание
7.4.0 Значением по умолчанию для параметра variant стала константа INTL_IDNA_VARIANT_UTS46 вместо устаревшего варианта INTL_IDNA_VARIANT_2003.
7.2.0 Константа INTL_IDNA_VARIANT_2003 устарела в пользу варианта INTL_IDNA_VARIANT_UTS46.

Примеры

Пример #1 Пример преобразования национального доменного имени функцией idn_to_ascii()

<?php

echo idn_to_ascii('täst.de');

?>

Результат выполнения приведённого примера:

xn--tst-qla.de

Пример #2 Пример обработки доменного имени, которое состоит только из ASCII-символов

<?php

// ASCII-домены функция только приводит к нижнему регистру
var_dump(idn_to_ascii('Example.com'));

?>

Результат выполнения приведённого примера:

string(11) "example.com"

Смотрите также

  • idn_to_utf8() - Преобразование доменного имени из IDNA ASCII в Unicode

Добавить

Примечания пользователей 4 notes

up
11
edible dot email at gmail dot com
13 years ago
The notes on this function are not very clear and a little misleading.

Firstly, <=5.3, you will need to make use of one of several scripts or classes available on the internet which might, or might not, require the installation of of the intl and idn PECL extensions ...and you will need to have !<4.0 in order to be able to install both.

Secondly, if you have >=5.4 you will not require the PECL extensions.

Third, use of utf8_encode() is not necessary. In fact, it will potentially prevent idn_to_ascii() from working at all.

On my setup it was necessary to change the charset in the script meta tags to UTF-8:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

...and to change charset_default in the php.ini file (/usr/local/lib/php.ini, whereis php.ini, find / -name php.ini):

default_charset = "UTF-8"

The above changes mean that idn_to_ascii() can now be used with that syntax (no need for utf8_encode()). Previously, the function worked to convert some IDNs, but failed to convert Japanese and Cyrillic IDNs. Further, no additional locales were enabled or added, and Apache's charset file was left unmodified.

It is also important to remember only to apply the function where required, eg:

idn_to_ascii(cåsino.com) // is wrong

...whereas...

iden_to_ascii(cåsino) // is right

...and also be aware of text editors that don't support UTF-8 encoding, or the $domain = 'cåsino' value will end up as $domain = '??????' ...and the function will fail.

I have found that Notepad++ easily and reliably handles UTF-8 encoding that works for this function using UTF-8 as the encoding option, not UTF-8 without BOM.
up
7
mschrieck at gmail dot com
8 years ago
To convert IDN Domains with the IDNA2008 definition use following command.

idn_to_ascii('teßt.com',IDNA_NONTRANSITIONAL_TO_ASCII,INTL_IDNA_VARIANT_UTS46)

The result is then as expected

xn--tet-6ka.com
up
1
alexchexes at gmail dot com
2 years ago
idn_to_ascii and idn_to_utf8 functions don't properly handle full URLs (i.e. with schema and paths), so here's the helper functions which handles all URLs, including ones with path but without a scheme

<?php
/**
* Converts URLS to punycode
* It doesn't url-encodes other parts
* The initial code from snipp dor ru website, here is modified version that handles urls without scheme
*/
function punycode_encode($url)
{
$no_scheme = false;
if (!
preg_match('/^.+?:\/\//', $url) && substr($url, 0, 2) !== '//') {
$url = '//' . $url;
$no_scheme = true;
}

$parts = parse_url($url);

$out = '';
if (!empty(
$parts['scheme'])) $out .= $parts['scheme'] . ':';
if (!empty(
$parts['host'])) $out .= '//';
if (!empty(
$parts['user'])) $out .= $parts['user'];
if (!empty(
$parts['pass'])) $out .= ':' . $parts['pass'];
if (!empty(
$parts['user'])) $out .= '@';
if (!empty(
$parts['host'])) $out .= idn_to_ascii($parts['host']);
if (!empty(
$parts['port'])) $out .= ':' . $parts['port'];
if (!empty(
$parts['path'])) $out .= $parts['path'];
if (!empty(
$parts['query'])) $out .= '?' . $parts['query'];
if (!empty(
$parts['fragment'])) $out .= '#' . $parts['fragment'];

if (
$no_scheme) {
$out = substr($out, 2);
}

return
$out;
}

function
punycode_decode($url)
{
$no_scheme = false;
if (!
preg_match('/^.+?:\/\//', $url) && substr($url, 0, 2) !== '//') {
$url = '//' . $url;
$no_scheme = true;
}

$parts = parse_url($url);
$out = '';
if (!empty(
$parts['scheme'])) $out .= $parts['scheme'] . ':';
if (!empty(
$parts['host'])) $out .= '//';
if (!empty(
$parts['user'])) $out .= $parts['user'];
if (!empty(
$parts['pass'])) $out .= ':' . $parts['pass'];
if (!empty(
$parts['user'])) $out .= '@';
if (!empty(
$parts['host'])) $out .= idn_to_utf8($parts['host']);
if (!empty(
$parts['port'])) $out .= ':' . $parts['port'];
if (!empty(
$parts['path'])) $out .= $parts['path'];
if (!empty(
$parts['query'])) $out .= '?' . $parts['query'];
if (!empty(
$parts['fragment'])) $out .= '#' . $parts['fragment'];

if (
$no_scheme) {
$out = substr($out, 2);
}

return
$out;
}
up
0
mpf at mk dot de
1 year ago
The documentation ist not clear what failure in the return section means. This should be substituted to something like this:

"Returns failure if the given string could not be converted".
To Top