Blog. Just Blog

Работа с Punycode на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Согласно существующим стандартам, любое доменное имя может состоять только из 26 символов латинского алфавита, цифр от 0 до 9 и символа дефиса. До момента, как ICANN разрешила использование символов национальных алфавитов, это правило безоговорочно соблюдалось. Теперь же эти ваши интернеты забиты сайтами с доменами на иероглифах, кириллице, всяких умляутах и прочем юникоде. Лично я считаю, что использование любых национальных символов в доменах, ссылках и именах файлов в интернете должно быть категорически запрещено. Но так как мое мнение в этом вопросе значения не имеет, приходится работать с тем, что есть. Для преобразования домена из национальной кодировки в ACE-последовательность в PHP существует функция idn_to_ascii. Но если бы она работала как надо, то и этой статьи бы не появилось.
  1. // Только домен, конвертирует правильно
  2. $url='СуперСайт.рф';
  3. echo idn_to_ascii($url);
  4. // xn--80ajnvgddkc.xn--p1ai
  5.  
  6. // Ссылка целиком, конвертирует с ошибкой
  7. $url='https://СуперСайт.рф/login/?id=123#result';
  8. echo idn_to_ascii($url);
  9. // xn--https://-86g3c5b4doldsk.xn--/login/?id=123#result-pir2e
Суть проблемы в том, что idn_to_ascii корректно работает только с "чистым" доменом, если ей передать на обработку всю ссылку целиком, то на выходе получится вообще не то, что надо. А на практике чаще всего приходится сталкиваться именно со ссылками.

Все решается при помощи вот такой небольшой функции. Если из ссылки удалось извлечь имя домена, то он преобразуется в ACE-последовательность и заменяется, иначе строка преобразуется целиком как есть.
  1. function punycode_encode($url) {
  2.     if ($domain=parse_url($url,PHP_URL_HOST)) {
  3.         return str_replace($domain,idn_to_ascii($domain),$url);
  4.     }
  5.     else {
  6.         return idn_to_ascii($url);
  7.     }
  8. }
Вот теперь все работает как надо:
  1. $url='СуперСайт.рф';
  2. echo punycode_encode($url);
  3. // xn--80ajnvgddkc.xn--p1ai
  4.  
  5. $url='https://СуперСайт.рф/login/?id=123#result';
  6. echo punycode_encode($url);
  7. // https://xn--80ajnvgddkc.xn--p1ai/login/?id=123#result
Для обратной конвертации надо просто заменить idn_to_ascii на функцию idn_to_utf8.

Поделиться ссылкой ВКонтакте
Просмотров: 990 | Комментариев: 0

Метки: PHP
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0039 сек.) / Память: 4.5 Mb
Наверх