Как работать с диакритическими знаками (диакритическими знаками) при переписывании "красивых URL-адресов"

Я переписываю URL-адреса, чтобы включить в них названия туристических блогов, созданных пользователями.

Я делаю это как для удобочитаемости URL-адресов, так и для целей SEO.

 http://www.example.com/gallery/280-Gorges_du_Todra/

Первое целое число - это id, остальное - для нас, людей (но не имеет значения для запроса ресурса).

Теперь люди могут писать заголовки, содержащие любой символ UTF-8, но большинство из них не разрешено в URL-адресе. Моя аудитория в основном англоговорящая, но, поскольку они путешествуют, они любят использовать такие имена, как

 Aït Ben Haddou

Как правильно перевести это для отображения в URL-адресе с помощью PHP в Linux.

Пока что видел несколько решений:

  1. просто удалите все недопустимые символы, замените пробелы это дает странные результаты:
    'Aït Ben Haddou' → /gallery/280-At_Ben_Haddou/
    Не очень полезно.

  2. просто удалите все недопустимые символы, замените пробелы, оставьте кодировку (stackoverflow.com), скорее всего, из-за использования 'regex-hammer' это дает странные результаты: 'tést tést' → /questions/0000/t233st-t233st

  3. переведите в "ближайший эквивалент"
    'Aït Ben Haddou' → /gallery/280-Ait_Ben_Haddou/
    Но это идет не так с немецким языком; например, «ü» следует транслитерировать как «уэ».

Для меня, как для голландца, третий результат `` выглядит '' лучше всего. Однако я совершенно уверен, что (1) многие люди будут иметь другое мнение и (2) это просто неверно в немецком примере.

Еще одна проблема с 3-м вариантом: как найти все возможные символы, которые можно преобразовать в 7-битный эквивалент?

Итак, вопрос:

  1. что, по вашему мнению, является наиболее желательным результатом. (в технических пределах)

  2. Как ее решить технически. (достичь желаемого результата) с помощью PHP.

«Ü» на самом деле будет записано как «ue». «Oe» - это «ö». :)

Bombe 21.01.2009 19:36
IDNA
Doug Currie 21.01.2009 19:39

Мне известны интернационализированные доменные имена, но они не решают проблему для этого пути к ресурсам и не очень удобочитаемы.

Jacco 21.01.2009 19:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
19
3
7 339
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Для меня наиболее читаема третья.

Вы можете использовать небольшой словарь, например. ï -> i и ü -> ue, чтобы указать, как вы хотите переводить различные символы.

проблема в том, что он по-разному переводится на французский и немецкий, не говоря уже о турецком или вьетнамском.

Jacco 21.01.2009 19:48

Возможно, используйте разные словари (если вы знаете, какой это язык) или всегда используйте самый простой словарь, например. ü -> u.

ChrisW 21.01.2009 19:55
Ответ принят как подходящий

В конце концов, для решения этой проблемы вам придется отказаться от идеи «правильно». Перевод строки, как бы вы это ни делали, разрушает точность во имя совместимости и удобочитаемости. Все три варианта одинаково совместимы, но №1 и №2 страдают с точки зрения удобочитаемости. Так что просто бегите и делайте то, что вам больше нравится - вариант №3.

Да, переводы для немецкого неверны, но если вы не начнете требовать от пользователей указывать, на каком языке написаны их заголовки (и ограничивая их только одним), вы не решите эту проблему без гораздо больших усилий, чем это того стоит. (Например, пропустить каждое слово в заголовке через словари для каждого известного языка и перевести диакритические знаки этого слова в соответствии с правилами его языка будет Работа, но это чрезмерно.)

В качестве альтернативы, если немецкий язык вызывает большее беспокойство, чем другие языки, сделайте свой перевод всегда с использованием немецкой версии, если таковая существует: äae, ëe, ïi, öoe, üue.

Редактировать:

Да, и что касается фактического метода, я бы перевел специальные случаи, если таковые имеются, через str_replace, а затем использовал iconv для остальных:

$text = str_replace(array("ä", "ö", "ü", "ß"), array("ae", "oe", "ue", "ss"), $text);
$text = iconv('UTF-8', 'US-ASCII//TRANSLIT', $text);

В качестве интересного примечания, на SO, кажется, ничего не имеет значения после идентификатора - это ссылка на эту страницу:

Как работать с диакритическими знаками (диакритическими знаками) при переписывании "красивых URL-адресов"

Очевидно, что мотивация состоит в том, чтобы разрешить изменение заголовка без разрыва ссылок, и вы можете также рассмотреть эту функцию.

Я использую аналогичную технику в проекте, за исключением случаев, когда предоставленный «ярлык» не совпадает, я автоматически 301 перехожу к правильному «ярлыку» (например, / questions / 465990 / why-does-this-link-go-to -the-same-place перенаправит на / questions / 465990 / how-to-handle-diacritics-acnts-when-rewr iting-pretty-urls). Я думаю, что это обычно желательно с точки зрения SEO и общих веб-стандартов: в идеале ресурс должен быть доступен по одному или максимум нескольким URL-адресам, а не по миллионам, которые SO в настоящее время допускает.

Frank Farmer 17.06.2009 02:36

Now people can write titles containing any UTF-8 character, but most are not allowed in the URL.

Напротив, разрешено большинство. См., Например, URL-адреса Википедии - такие вещи, как http://en.wikipedia.org/wiki/Café (также известный как http://en.wikipedia.org/wiki/Caf%C3%A9), отображаются красиво - даже если подсветка StackOverflow не выделяет их правильно :-)

Уловка заключается в том, чтобы надежно их прочитать в любой среде хостинга; есть проблемы с серверами CGI и Windows, в частности, например, с IIS.

Конечно, поддержка достаточно неоднородна, и ваш ответ даже дает пример того, почему вы обычно не хотите этого делать - URL-распознаватель SO обрезает «é» в вашем примере Café.

Ben Blank 21.01.2009 20:45

Мой браузер (Safari) делает это за меня автоматически. Каждый URL-адрес, который я ввожу в поле адреса, отправляется в кодировке UTF-8.

Gumbo 21.01.2009 20:45

Я должен поддерживать его совместимость с древними компьютерами, которые можно найти в интернет-кафе по всему миру. Но, может быть, мне следовало сказать: старые школьные URL :)

Jacco 21.01.2009 21:15

Хорошая тема, у меня была такая же проблема некоторое время назад. Вот как я это исправил:

function title2url($string=null){
 // return if empty
 if (empty($string)) return false;

 // replace spaces by "-"
 // convert accents to html entities
 $string=htmlentities(utf8_decode(str_replace(' ', '-', $string)));

 // remove the accent from the letter
 $string=preg_replace(array('@&([a-zA-Z]){1,2}(acute|grave|circ|tilde|uml|ring|elig|zlig|slash|cedil|strok|lig){1};@', '@&[euro]{1};@'), array('${1}', 'E'), $string);

 // now, everything but alphanumeric and -_ can be removed
 // aso remove double dashes
 $string=preg_replace(array('@[^a-zA-Z0-9\-_]@', '@[\-]{2,}@'), array('', '-'), html_entity_decode($string));
}

Вот как работает моя функция:

  1. Преобразуйте его в HTML-сущности
  2. Уберите акценты
  3. Удалите все оставшиеся странные символы

Вы можете использовать htmlentities (str_replace ('', '-', $ string), ENT_QUOTES, "UTF-8"));

Adrian B 08.12.2011 16:02

Это хорошая функция:

function friendlyURL($string) {
    setlocale(LC_CTYPE, 'en_US.UTF8');
    $string = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $string);
    $string = str_replace(' ', '-', $string);
    $string = preg_replace('/\\s+/', '-', $string);
    $string = strtolower($string);
    return $string;
}

Другие вопросы по теме