Преобразование punycode в PHP

Преобразование punycode в PHP

Punycode – это специальная кодировка, используется для преобразования символов Unicode в ASCII для кодирования интернационализированных доменных имен (IDN).

В PHP есть функции для преобразования:

echo idn_to_ascii('домен.рф'); // xn--d1acufc.xn--p1ai

echo idn_to_utf8('xn--d1acufc.xn--p1ai'); // домен.рф
PHP

Но с ними есть одна проблема – они неправильно работает с полными URL, например:

echo idn_to_ascii('http://домен.рф/category'); // xn--http://-5ggj3emj.xn--/category-k3h8b
PHP

Чтобы перекодировать домен в ссылке, нужно разбирать URL с помощью parse_url, сделать преобразование и собрать обратно.

function punycode_encode($url)
{
	$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'];

	return $out;
}

echo punycode_encode('http://домен.рф/category'); // http://xn--d1acufc.xn--p1ai/category
PHP

Обратный перевод

function punycode_decode($url)
{
	$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'];

	return $out;
}

echo punycode_decode('http://xn--d1acufc.xn--p1ai/category'); // http://домен.рф/category
PHP
02.10.2019
10176

Комментарии

, чтобы добавить комментарий.

Другие публикации

Автоматическое сжатие и оптимизация картинок на сайте
Изображения нужно сжимать для ускорения скорости загрузки сайта, но как это сделать? На многих хостингах нет...
30240
+7
Подключение к платежной системе Сбербанка
После регистрации в системе эквайринга Сбербанка и получив доступ к тестовой среде, можно приступить к интеграции с...
69304
+25
CURL - если сервер отдает редирект
Бывает так что сервер перенаправляет на другой URL. Например Google, если перейти на https://google.com c IP из РФ он...
14955
+2
Поиск похожих текстов в базе данных MySQL + PHP
Один из вариантов поиска похожих статей в базе данных основан на схождении слов в двух текстах.
7962
+6
Публикация записей на стену сообщества VK
Для начала вы должны быть авторизированы в VK и являться администратором группы или страницы. Далее нужно создать...
32865
+9
PHP-класс обертка для PDO
Класс значительно упрощает работу с PDO, сокращает код. Реализован на статических классах и не требует создание экземпляра класса.
24116
+12