Преобразование 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

Комментарии

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

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

Изображения нужно сжимать для ускорения скорости загрузки сайта, но как это сделать? На многих хостингах нет...
7758
+5
Бывает так что сервер перенаправляет на другой URL. Например Google, если перейти на https://google.com c IP из РФ он...
4713
+1
После регистрации в системе эквайринга Сбербанка и получив доступ к тестовой среде, можно приступить к интеграции с...
17597
+12
Класс значительно упрощает работу с PDO, сокращает код. Реализован на статических классах и не требует создание экземпляра класса.
9602
+4
Несколько примеров как перевести цвета из HEX в RGB и обратно с помощью PHP.
2481
+1
Для начала вы должны быть авторизированы в VK и являться администратором группы или страницы. Далее нужно создать...
13343
+3