Хороший пример реализации роутинга/чпу?

Не буду вдаваться в историю проекта. Скажу, что сейчас подходит этап, когда у программистов появится время, на частичное переписывание старого и страшного кода. Приоритетной считаю систему ЧПУ. Работает она примерно так:

— Класс ЧПУ, делает explode URL по слэшам(потом появился костыль, приравнивающий "_" к "/").

— Первый элемент массива — имя модуля. Огромный свитч, который находит и передает управление модулю.

— Специальный метод модуля, являет собой миничпу, по тому же принципу. Разбирает уже второй параметр и передает управлению нужному методу.


Система в принципе работает, раньше было ещё хуже и даже нужный метод модуля в основном классе ЧПУ вызывался, следствием чего, часто было, что какие-либо функции отпадали при переписывание. Но проблема даже не в этом, а в том, что возникают не удобства с параметрам в URL. Если например /news/1740/page/2

То приходится ориентироваться на порядок параметров, что не есть хорошо, если некоторые, например, не будут учавстовать.


Прошу совета и праведного пинка.

Фреймворки с хорошей и гибкой системой роутинга, недавно видел у Kohana, заинтересовался. Прикручивать целый фреймворк скорее всего не будем. Интересен ваш опыт, советы, может быть нюансы на которые лучше посмотреть. Примеры из других фреймворков, сейчас хороших много, а каждый изучать времени нет.

Проект на PHP.


Спасибо за внимание и потраченное на меня время.
Надеюсь задал вопрос и описал проблему понятно. Будут уточнения — вперед. Плюсами одарю:)
  • Вопрос задан
  • 10258 просмотров
Пригласить эксперта
Ответы на вопрос 5
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
symfony.com/doc/current/book/routing.html — ознакомьтесь, возможно вам будет любопытно.

В любом случае, делать жесткую структуру ссылок нерентабельно. Лучше описывать правила маршрутизации хотя бы как в Yii (просто паттерны регулярных выражений).
Ответ написан
MpaK999
@MpaK999
Буду!
Посмотрите как реализован роутинг в Ruby on Rails, ничто не мешает реализовать подобное же на PHP
Ответ написан
@Big_Shark
Посмотрите как сделано в CMF laravel.com/docs/routing, очень гибкая и удобная структура получается.
Ответ написан
Комментировать
FanKiLL
@FanKiLL
У меня правда для java.
routes = new ArrayList<RouteData>();
routes.add(new RouteData("GET", "home/index/{^[0-9]{1,15}$}/valid/{^[A-z]{3,15}$}"));
routes.add(new RouteData("POST", "home/index/{^[0-9]{1,15}$}/valid/{^[A-z]{3,15}$}"));


Я в своё время решил параметры держать в {} скобках, так парсер знает что это параметр + можно регулярку туда засунуть, чтоб роутинг чётко совпадал. Плюс держа в скобках, вы можете делать роутинг не по паттерну Controller/Action/id А что-нибуть более гибкое(особенно с регулярками описывающие парраметр)

Controller/Action/{id}
Controller/{id}/Action
Controller/Action/{name}/delete/{id}


Плюс в моём примере метод запроса (POST, GET DELETE...) тоже имеет значение.
Парсер роутера, разбирает пришедший запрос и ищет есть ли такой роутинг у нас, при первом же совпадение, например
Question/Read/{name}/{id} + метод запроса тоже должен совпадать.

Запустится Controller = Question, Action = Read с параметрами name, id

Конечно с помощью reflection проверяется есть ли такой контроллер и action метод с такими параметрами если нет — 404

Вообщем как то так, трудно описать, если что спрашивайте. Но думаю принцип понятен.

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

Http Method Delete: User/Profile/{name}/delete/{id} параметр delete в url не играет никакой роли, он просто для удобства и понимания что делает URL.
Ответ написан
Комментировать
@tarya
Я в своей cms сделал достаточно просто и работает как часы.

Все примерно так:

При инициализации страницы дергается метод parseBaseURL() в нем вычленяются из $_SERVER[«REQUEST_URI»] базовые переменные. А базовые для движка такие /ru/section/document.html

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

Далее. Вот пример: посетитель зашел по урлу /news/ — это у нас раздел сайта. В нем дергается модуль. Все что будет далее строиться например /news/page-1/, /news/view-1/, /news/download/file.zip или как угодно и что угодно может быть в урле. Как я это все распознаю. Базовый разбор был еще при инициализации, далее как я сказал дергается раздел, а к нему прицеплен модуль. В модуле я могу задать любой шаблон для урла.

Например:

$u_goods->addURL("#/cat-(\d+)/?#i", «category»);//add cat
$u_goods->addURL("#/goods-(\d+)/?#i", «goods»);//add goods
$u_goods->addURL("#/page-(\d+)/?$#i", «p»);//add pages var

И все. Уже в классе становятся доступные переменные category, goods, p. И так далее.

Итого — урл может быть какой угодно, и всегда в модуле для любого угла можно задать свое правило.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽