Функция PHP для декодирования Punycode.

PHP функция и класс для декодирования Punycode в инторнациональный формат включая рускоязычные символы.и.

Задача: Нужна PHP функция или класс которая позволяет перекодировать имя домена в формате Punycode в удобочитаемый формат. Например найти в URL код xn--80aeel0ci0fza.xn--p1ai и заменить как “здравься.рф”. Пример и описание работы.

Ответ AI ChatGPTОтвет AI ChatGPT: Конечно, вот PHP функция и класс для преобразования доменных имен Punycode в удобочитаемый формат (IDN - Internationalized Domain Name):

Функция декодер Punycode:

PHP
<?php

/**
 * Преобразует доменное имя из Punycode в удобочитаемый формат (IDN).
 *
 * @param string $domain Доменное имя в Punycode (например, xn--80aeel0ci0fza.xn--p1ai).
 * @return string|false Доменное имя в удобочитаемом формате (например, здравься.рф), или false в случае ошибки.
 */
function punycode_decode(string $domain): string|false
{
    // Используем функцию idn_to_utf8, если она доступна.
    if (function_exists('idn_to_utf8')) {
        return idn_to_utf8($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $info);
    }

    // Если idn_to_utf8 недоступна (например, старая версия PHP),
    // попробуем альтернативный подход (если у вас установлен пакет "ext-intl").
    if (extension_loaded('intl')) {
        try {
            $decoded = idn_to_utf8($domain);
            if ($decoded !== false) {
                return $decoded;
            }
        } catch (\Exception $e) {
            // Обработка ошибки, если idn_to_utf8 не смогла обработать домен.
            return false;
        }
    }

    // Если нет idn_to_utf8 и intl, возвращаем false.
    return false;
}


// Пример использования:
$domain_punycode = 'xn--80aeel0ci0fza.xn--p1ai';
$domain_readable = punycode_decode($domain_punycode);

if ($domain_readable) {
    echo "Punycode: " . $domain_punycode . "\n";
    echo "Readable: " . $domain_readable . "\n"; // Выведет: здравься.рф
} else {
    echo "Ошибка при декодировании Punycode.\n";
}
?>

Класс декодер Punycode:

PHP
<?php

class PunycodeConverter
{
    /**
     * Преобразует доменное имя из Punycode в удобочитаемый формат (IDN).
     *
     * @param string $domain Доменное имя в Punycode.
     * @return string|false Доменное имя в удобочитаемом формате, или false в случае ошибки.
     */
    public function decode(string $domain): string|false
    {
        // Используем idn_to_utf8, если она доступна.
        if (function_exists('idn_to_utf8')) {
            return idn_to_utf8($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $info);
        }

        // Если idn_to_utf8 недоступна (например, старая версия PHP),
        // попробуем альтернативный подход (если у вас установлен пакет "ext-intl").
        if (extension_loaded('intl')) {
            try {
                $decoded = idn_to_utf8($domain);
                if ($decoded !== false) {
                    return $decoded;
                }
            } catch (\Exception $e) {
                // Обработка ошибки, если idn_to_utf8 не смогла обработать домен.
                return false;
            }
        }


        // Если нет idn_to_utf8 и intl, возвращаем false.
        return false;
    }

    /**
     * Преобразует доменное имя в Punycode.
     *
     * @param string $domain Доменное имя в удобочитаемом формате.
     * @return string|false Доменное имя в Punycode, или false в случае ошибки.
     */
    public function encode(string $domain): string|false
    {
        if (function_exists('idn_to_ascii')) {
            return idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $info);
        }
        return false;
    }
}

// Пример использования класса:
$converter = new PunycodeConverter();

$domain_punycode = 'xn--80aeel0ci0fza.xn--p1ai';
$domain_readable = $converter->decode($domain_punycode);

if ($domain_readable) {
    echo "Punycode: " . $domain_punycode . "\n";
    echo "Readable: " . $domain_readable . "\n"; // Выведет: здравься.рф
} else {
    echo "Ошибка при декодировании Punycode.\n";
}

$domain_readable = "здравься.рф";
$domain_encoded = $converter->encode($domain_readable);

if ($domain_encoded) {
    echo "Readable: " . $domain_readable . "\n";
    echo "Punycode: " . $domain_encoded . "\n"; // Выведет: xn--80aeel0ci0fza.xn--p1ai
} else {
    echo "Ошибка при кодировании Punycode.\n";
}

?>

Описание работы:

Функция punycode_decode() и метод decode():Принимает на вход строку с доменным именем в Punycode.Проверяет, доступна ли функция idn_to_utf8() (часть расширения intl). Это стандартный и предпочтительный способ.Если idn_to_utf8() доступна, она используется для преобразования.Если idn_to_utf8() недоступна, но установлено расширение intl, функция пытается использовать idn_to_utf8(). Это может помочь в некоторых случаях, если idn_to_utf8 не доступна напрямую, но расширение установлено.Если и idn_to_utf8() и intl не доступны, функция возвращает false, указывая на ошибку.

Метод encode():Принимает на вход строку с доменным именем в удобочитаемом формате.Использует функцию idn_to_ascii() (из расширения intl) для преобразования в Punycode.Возвращает доменное имя в Punycode или false в случае ошибки.

Пример использования:В обоих вариантах (функция и класс) показано, как использовать функцию/метод для преобразования Punycode в удобочитаемый формат. Также показан пример кодирования из удобочитаемого формата в Punycode, в случае использования класса.

Требования:

  • Расширение intl в PHP: Для работы этих функций необходимо, чтобы в вашем PHP было установлено и включено расширение intl. Это расширение предоставляет функции для работы с интернационализацией, включая поддержку IDN. В большинстве современных PHP-окружениях intl установлено по умолчанию или может быть легко установлено через менеджер пакетов (например, apt-get install php-intl в Debian/Ubuntu, или через PECL).
  • PHP версии 5.3 и выше: Функция idn_to_utf8() появилась в PHP 5.3.

Как установить/проверить intl в PHP:

Проверка из командной строки:

php -m | grep intl

Если intl есть в списке, расширение установлено.

Проверка в скрипте PHP: Создайте файл info.php со следующим содержимым:

PHP
<?php
phpinfo();
?>

Загрузите этот файл в браузере (например, http://localhost/info.php). Найдите раздел intl в выводе. Если раздел есть, расширение установлено.

 

Установка (Debian/Ubuntu):

sudo apt-get update
sudo apt-get install php-intl
sudo systemctl restart apache2  # или ваш веб-сервер

Установка (CentOS/RHEL):

sudo yum install php-intl
sudo systemctl restart httpd  # или ваш веб-сервер

Важно: После установки или включения расширения intl, вам может потребоваться перезапустить ваш веб-сервер (Apache, Nginx и т.д.), чтобы изменения вступили в силу.

Этот код должен корректно преобразовывать Punycode-домены в удобочитаемые, если у вас правильно установлено расширение intl. Если у вас возникнут проблемы, пожалуйста, предоставьте информацию о вашей PHP версии и настройках, а также любые сообщения об ошибках, которые вы видите.

Дата публикации: 

ТОП 10 случайных публикаций



Сайт разработан студией © WEB-VidST   


Яндекс.Метрика