Я переписываю 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/
Не очень полезно.
просто удалите все недопустимые символы, замените пробелы, оставьте кодировку (stackoverflow.com), скорее всего, из-за использования 'regex-hammer'
это дает странные результаты:
'tést tést' → /questions/0000/t233st-t233st
переведите в "ближайший эквивалент" 'Aït Ben Haddou' → /gallery/280-Ait_Ben_Haddou/
Но это идет не так с немецким языком; например, «ü» следует транслитерировать как «уэ».
Для меня, как для голландца, третий результат `` выглядит '' лучше всего. Однако я совершенно уверен, что (1) многие люди будут иметь другое мнение и (2) это просто неверно в немецком примере.
Еще одна проблема с 3-м вариантом: как найти все возможные символы, которые можно преобразовать в 7-битный эквивалент?
Итак, вопрос:
что, по вашему мнению, является наиболее желательным результатом. (в технических пределах)
Как ее решить технически. (достичь желаемого результата) с помощью PHP.
Мне известны интернационализированные доменные имена, но они не решают проблему для этого пути к ресурсам и не очень удобочитаемы.






Для меня наиболее читаема третья.
Вы можете использовать небольшой словарь, например. ï -> i и ü -> ue, чтобы указать, как вы хотите переводить различные символы.
проблема в том, что он по-разному переводится на французский и немецкий, не говоря уже о турецком или вьетнамском.
Возможно, используйте разные словари (если вы знаете, какой это язык) или всегда используйте самый простой словарь, например. ü -> u.
В конце концов, для решения этой проблемы вам придется отказаться от идеи «правильно». Перевод строки, как бы вы это ни делали, разрушает точность во имя совместимости и удобочитаемости. Все три варианта одинаково совместимы, но №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, кажется, ничего не имеет значения после идентификатора - это ссылка на эту страницу:
Очевидно, что мотивация состоит в том, чтобы разрешить изменение заголовка без разрыва ссылок, и вы можете также рассмотреть эту функцию.
Я использую аналогичную технику в проекте, за исключением случаев, когда предоставленный «ярлык» не совпадает, я автоматически 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 в настоящее время допускает.
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é.
Мой браузер (Safari) делает это за меня автоматически. Каждый URL-адрес, который я ввожу в поле адреса, отправляется в кодировке UTF-8.
Я должен поддерживать его совместимость с древними компьютерами, которые можно найти в интернет-кафе по всему миру. Но, может быть, мне следовало сказать: старые школьные URL :)
Хорошая тема, у меня была такая же проблема некоторое время назад. Вот как я это исправил:
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));
}
Вот как работает моя функция:
Вы можете использовать htmlentities (str_replace ('', '-', $ string), ENT_QUOTES, "UTF-8"));
Это хорошая функция:
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;
}
«Ü» на самом деле будет записано как «ue». «Oe» - это «ö». :)