Подтвердить что ты не робот

Как обращаться с диакритикой (акцентами) при переписывании "хороших URL-адресов"

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

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

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

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

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

 Aït Ben Haddou

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

До сих пор я видел несколько решений:

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Edit:

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

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

Ответ 2

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

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

Ответ 3

Как интересная сторона примечания, на SO ничего не имеет значения после ID - это ссылка на эту страницу:

Как обращаться с диакритикой (акцентами) при переписывании "хороших URL-адресов"

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

Ответ 4

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

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));
}

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

  • Преобразовать его в html-объекты
  • Разделите акценты
  • Удалите все оставшиеся странные символы

Ответ 5

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

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

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

Ответ 6

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

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;
}