Я переписываю URL-адреса, чтобы включить заголовок созданных пользователем рекламных блоков.
Я делаю это как для чтения URL-адресов, так и для SEO-целей.
http://www.example.com/gallery/280-Gorges_du_Todra/
Первое целое число – это id, остальное для нас – люди (но не имеет значения для запроса ресурса).
Теперь люди могут писать заголовки, содержащие любой символ UTF-8, но большинство из них не разрешено в URL-адресе. Моя аудитория, как правило, говорит по-английски, но, поскольку они путешествуют, им нравится включать такие имена, как
Айт Бен Хадду
Каков правильный способ перевести это для отображения в URL-адресе с помощью PHP на linux.
До сих пор я видел несколько решений:
просто разделите все не разрешенные символы, замените пробелы, это имеет странные результаты:
'Aït Ben Haddou' → /gallery/280-At_Ben_Haddou/
Не очень полезно.
просто разделите все не допустимые символы, замените пробелы, оставьте charcode (stackoverflow.com), скорее всего, из-за использования «regex-hammer»
это дает странные результаты: 'tést tést' → /questions/0000/t233st-t233st
перевести на «ближайший эквивалент»
'Aït Ben Haddou' → /gallery/280-Ait_Ben_Haddou/
Но это не так для немецкого; например, «ü» следует транслитерировать «ue».
Для меня, как голландский человек, 3-й результат «выглядит» лучшим.
Я вполне уверен, однако, что (1) у многих людей будет другое мнение, и (2) это просто неправильно в немецком примере.
Еще одна проблема с третьим вариантом: как найти все возможные символы, которые можно преобразовать в 7-битный эквивалент?
Итак, вопрос:
что, на ваш взгляд, является наиболее желательным результатом. (в пределах технических ограничений)
Как технически решить эту проблему. (достичь желаемого результата) с помощью PHP.
В конечном итоге вам придется отказаться от идеи «правильно», для этой проблемы. Перевод строки, независимо от того, как вы это делаете, разрушает точность во имя совместимости и удобочитаемости. Все три варианта одинаково совместимы, но №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);
Для меня третий – наиболее читаемый.
Вы можете использовать небольшой словарь, например, ï -> i
и ü -> ue
чтобы указать, как вы хотите перевести различные символы.
Как интересная сторона примечания, на SO ничего, похоже, не имеет никакого значения после ID – это ссылка на эту страницу:
Как обращаться с диакритикой (акцентами) при переписывании «хороших 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)); }
Вот как работает моя функция:
Теперь люди могут писать заголовки, содержащие любой символ UTF-8, но большинство из них не разрешено в URL-адресе.
Наоборот, большинство разрешено. См. Например, URL-адрес Википедии – такие вещи, как http://en.wikipedia.org/wiki/Café (aka http://en.wikipedia.org/wiki/Caf%C3%A9 ) отображаются хорошо – даже если маркер StackOverflow не работает, t правильно их выберете 🙂
Трюк надежно читает их в любой среде хостинга; например, существуют проблемы с серверами CGI и Windows, в частности IIS.
Это хорошая функция:
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; }