#php
Есть такой роутинг
'/' => ['site', 'index'],
'/[s:action]' => ['site', '{action}'],
'/[s:controller]/[s:action]' => ['{controller}', '{action}'],
'/[s:module]/[s:controller]/[i:id]' => [ '{controller}', 'view', '{module}'], //$id
- параметр передаётся в action
'/[s:module]/[s:controller]/[s:action]/[i:id]' => ['{controller}', '{action}', '{module}'],
//$id - параметр передаётся в action
Как направить URL на нужные Controller и Action понятно.
Но теперь проблема с тем чтоб проанализировать обратные URL. И чтоб эта реализация
не использовала много ресурсов, так как скорее всего будет вызываться для генерации
множества ссылок на страницах.
Допустим нужно сформировать ссылки для примера:
'/' => '/',
'site/index' => '/',
'site/login' => '/login',
'user/info' => '/user/info'
'user/profile/view/123' => '/user/profile/123',
'user/profile/edit/123' => '/user/profile/edit/123',
примеры
Допустим мы вводим URL / и попадаем на контроллер site экнен index, теперь на основе
этого же правила нужно сделать обратное правила для redirect/rewriterule/reverseroute/alias
как еще назвать не знаю.
То есть нужно чтоб при вводе URL /site/index мы попадали на /
Допустим мы вводим URL /user/profile/123 попадаем в модуль user на контроллер profile
экнен view с параметром id=123,
Аналогично из правил роутинга нужно чтоб при вводе URL /user/profile/view/123 нас
редиректило на /user/profile/123
И т.д. По правилам роутинга описанным выше
Попробую еще раз
Пользователь вводит URL /
Роутинг срабатывает на первом правиле('/' => ['site', 'index']), и вызывается SiteController::index()
Всё отлично и хорошо.
Возможна другая ситуация, пользователь вводит URL site/index
Роутинг срабатывает на третьем правиле('/[s:controller]/[s:action]' => ['{controller}',
'{action}']), и также вызывает SiteController::index()
Потом приходит СЕОшник, и говорит, а почему у нас два URL отдают один и тот же контент,
это не комильфо. Сделай переадресацию на основную страницу, тоесть на /, и так для
всех правил описанных в роутинге.
Задаю вопрос на StackOverflow, как это сделать имея правила роутинга описанные выше.
'/' => ['site', 'index'] ====> '/site/index' => '/'
Немного про формат роутинга на всякий случай
Ключ - это условие по которому обрабатывается URL
s: - string
i: - integer
Значение - это массив состоящий из
controller
action
module
В явной форме или в виде {placeholder}, который берётся из URL по маске в ключе
Ответы
Ответ 1
То есть перечитав я усёк - у тебя несколько роутов ведут на один и тот же MCA (module controller action). Ты же хочешь, чтобы всегда оставалось только одно соответсвие URL <=> MCA - например чтобы редиректило, или выдавало 404. Добавлю ещё одно определение - роут, это шаблон(может быть строкой, массивом, коллбеком, и вообще чем угодно), по которому определённые URL адреса можно распарсить в MCA + массив параметров. Делается так - роутам добавляется параметр priority , или он может по умолчанию высчитываться от строковой длинны роута, например. Далее после этапа бутстрапа приложения - отсортируй роуты по priority. Предположим что для роутера ты завёл класс SomeRouter. Этот класс должен иметь как минимум два метода: parse (собрать MCA из URL-строки, может вернуть false - если URL не подходит ни единому роуту) и stringify (собрать MCA+прочие параметры в URL-строку). Этот класс содержит роуты (список, который в вопросе под фразой "Есть такой роутинг") Так вот при парсинге роута должен быть код, суть которого примерно: $requestMCA = SomeRouter::parse($URL); if (($goodURL = SomeRouter::stringify($requestMCA))!=$URL){ return redirect($goodURL); } Главная суть этого - как парсинг URL, так и сброрка URL - должны работать согласно предсказуемым приоритетам роутов : по приоретам работают циклы сбора/разбора внутри SomeRouter. При первом хите цикл сборки/разборки прерывается и возвращается результат. UPD: Обычно более конкретные роуты имеют более высокий приоритет, а менее конкретные - более низкий приоритет. Например роут / - наивысший приоритет, а роут /[s:module]/[s:controller]/[s:action]/* - низший приоритет.
Комментариев нет:
Отправить комментарий