#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]/* - низший приоритет.
Комментариев нет:
Отправить комментарий