PHP Routing с многоязычной поддержкой - PullRequest
4 голосов
/ 02 мая 2011

В настоящее время я создаю CMS на платформе.Я сделал мой файл .htaccess, который выглядит следующим образом:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^([A-Za-z]+)/(.*)$ index.php?url=$1 [PT,L]

</IfModule>

Моя проблема в том, что:

1) Доступ к моим страницам возможен по обычному URL-адресу MVC: http://example.com/pages/view/{the-shorttag-of-the-page}

2) Мои страницы также доступны по маршруту: http://example.com/p/{the-shorttag-of-the-page}

Что мне действительно нужно реализовать, так это то, что я могу получить к нему доступ двумя способами: http://example.com/{the-shorttag-of-the-page} Или сязыковая поддержка http://example.com/{lang}/{the-shorttag-of-the-page}

Моя проблема в том, что я не хочу менять mod_rewrite - я скорее хочу создавать маршруты в PHP, но я не могу найти решение о том, как маршрутизировать к PageController-> метод view () без статической буквы («p» в верхнем примере) в условиях.

Вы понимаете мой вопрос?И есть ли у вас какие-нибудь советы, которые могли бы привести меня в правильном направлении?

Ответы [ 2 ]

1 голос
/ 02 мая 2011

Звучит так, как будто вам нужно реализовать какой-то маршрутизатор.

Я сам с этим столкнулся, и вот как я сделал так, чтобы он работал довольно хорошо:

Некоторые классы маршрутизаторов анализируют URL,Он разбивает части URL (/en/controller/action/param1/paramval1/) на части.Он определяет код языка (по умолчанию, если не указан), контроллер, действие и т. Д. Маршрутизатор также предоставляет информацию (контроллер, имена действий, параметры) для других частей системы, хотя вы можете реализовать специальный класс для этой цели (например, Запрос),

Теперь различные части системы имеют доступ к данной информации через класс Router или Request.С этого момента должно быть легко реализовать многоязычный сайт.

Еще раз, важная часть - это сопоставление URL с контроллером и действием.Определенно, если вам не нужен URL, такой как /controller/action/parameter1, у вас должна быть некоторая таблица сопоставления (документ XML / таблица базы данных), которая сопоставляет заглушку (короткий тег страницы) с контроллером и действием.Именно маршрутизатор читает эту таблицу и определяет контроллер, действие и другие параметры на основе заданных правил.

Надеюсь, я не слишком усложнил:)

Обновление:

Что касается меня, я реализовал сопоставление с XML-файлом.Позвольте мне объяснить далее: маршрутизатор заботится о разрешении URL.Обычно ваш URL будет содержать имя контроллера и действия (в вашем случае страниц - это контроллер, view - это действие).

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

Я реализовал это как статические маршруты, записанные вручную в файл XML, но вы можете, например, использовать некоторый класс плагина, которыйпроверяет, действительно ли заглушка относится к странице.Если это не так, это может означать две вещи: это контроллер или запрос недействителен.

Позвольте мне поговорить о коллизиях: если заглушка совпадает с именем любого контроллера, вы столкнулись с коллизией,Стоит ли рендерить страницу с заданной заглушкой или вызывать контроллер?Это должно быть как-то решено, возможно, вы можете программно ограничить пользователя, чтобы иметь страницу с такими заглушками.

Кроме того, в следующий раз, когда вы погрузитесь в разработку приложений на PHP, я бы порекомендовал вам использовать некоторые хорошо известные фреймворки PHP (если вы еще этого не делаете, оф.), Например, Zend, Kohana или CodeIgniter.Все они предоставляют маршрутизатор и многие другие компоненты, которые делают разработку приложений намного проще, быстрее и безопаснее.

1 голос
/ 02 мая 2011

Я делаю это, передавая всю строку после домена на страницу индекса и обрабатывая ее в php, а не в .htaccess. Я не эксперт .htaccess, но это работает для меня:

RewriteEngine On  
RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

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

Спросите меня, пожалуйста, если вам нужно больше деталей.

ОБНОВЛЕНО

Деннис, я читал пост @usoban и могу сказать, что у меня похожий подход. Как я уже сказал, я получаю полный путь после домена от .htaccess к моему application классу и анализирую его в массив. Если в конфигурации указано «многоязычность», я беру первый элемент массива и загружаю таблицу «псевдонимов» для этого языка.

Таблица «псевдонимов» - это ассоциативный массив, который отображает контроллер псевдонимов, например:

$lang_mods = array(
    'home'      => 'Home',
    'contact'   => 'Contact',
    'sitemap'   => 'Sitemap',
    'about'     => 'Section/about',
    'terms'     => 'Section/terms',
);

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

http://www.example.com/en/contact а также: http://www.example.com/es/contacto

Итак, после удаления первого элемента языка из массива url я проверяю следующий элемент по таблице псевдонимов. Последние два элемента в таблице представляют собой особые случаи, которые можно использовать для упрощения URL, получая

http://www.example.com/en/about вместо http://www.example.com/en/section/about это выглядит лучше, но оба указывают на один и тот же Section контроллер.

После удаления языка и псевдонима остальные элементы в массиве -if any-передаются в контроллер. 'about' или 'term' в примере добавляются в массив аргументов. В зависимости от контроллера, первый аргумент может быть действием или нет.

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

Хорошо, в вашем случае, может быть, если первый аргумент (или второй, если сайт многоязычный) можно проверить на наличие доступных контроллеров, если он не существует, вы можете перенаправить на контроллер по умолчанию, и затем сверяясь с доступными страницами в вашей базе данных. Таким образом, вы можете избежать необходимости иметь дополнительный /p/ в URL.

Я пытался прояснить, извините, английский не мой родной язык;)

...