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

Поделится

Темы

PHP URL Домены

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

Изображения нужно сжимать для ускорения скорости загрузки сайта, но как это сделать? На многих хостингах нет...
26.10.2018 2094
Бывает так что сервер перенаправляет на другой URL. Например Google, если перейти на https://google.com c IP из РФ он...
16.11.2017 1441
Класс значительно упрощает работу с PDO, сокращает код. Реализован на статических классах и не требует создание...
14.03.2018 3721
Для начала вы должны быть авторизированы в VK и являться администратором группы или страницы. Далее нужно создать...
16.11.2016 7953
После регистрации в системе эквайринга Сбербанка и получив доступ к тестовой среде, можно приступить к интеграции с...
22.10.2018 4857
Можно найти множество применений Яндекс Диска на своем сайте, например, хранение бекапов и отчетов, обновление прайсов,...
29.11.2017 9971