За последние 24 часа нас посетили 22622 программиста и 1016 роботов. Сейчас ищут 725 программистов ...

Пересечение динамических параметров маршрутов

Тема в разделе "Laravel", создана пользователем MasterDmx, 10 июл 2020.

  1. MasterDmx

    MasterDmx Активный пользователь

    С нами с:
    17 авг 2014
    Сообщения:
    31
    Симпатии:
    0
    Всем привет, начал осваивать фрейворк laravel (v7), раньше писал на чистом php, то есть многого не знаю.

    Проблема: есть 2 маршрута с городами и услугами, которые в урле находятся на одном уровне в виде слагов. Слаги хранятся в бд. Маршруты должны обрабатываться разными контроллерами.

    Пример урлов:
    • site.ru/tyumen
    • site.ru/remont
    Пример маршрутов:

    Код (Text):
    1. Route::get('{city}', 'HomeController@index');
    2. Route::get('{service}', 'ServiceController@index');
    Как видно, происходит пересечение параметров. Если в урле указан "remont", то он попадает под маршрут городов и лара пытается найти его в таблице городов, что соответственно фейлится и лара с гордостью отдает 404, а до второго маршрута дело не доходит.

    Алгоритм: необходимо задать свою логику обработки маршрута с городами. То есть если маршрут городов подходит - необходимо сделать запрос в бд, проверив есть ли там такой слаг, если есть - маршрут подходит - идем в контроллер, если нет - маршрут не подходит и поиск нужно продолжить, тем самым наткнувшись на маршрут с услугами, и если там есть - в контроллер, а если нет - 404.

    Как это сделать? В документации инфы по тому, как можно повлиять на логику обнаружения для конкретного маршрута не нашел. Может быть это как-то через middleware делается?

    Конечно можно вручную указать значения в регулярке, но это не подходит, так как города и услуги забиваются в админке. Варианты со сменой маршрутов путем добавления еще одного уровня (gorod/tyumen | uslugi/remont) или ключей (gorod-tyumen | uslugа-remont) тоже не подходят.

    В общем буду рад помощи)
     
    #1 MasterDmx, 10 июл 2020
    Последнее редактирование: 10 июл 2020
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Решать внутри обработчика только, хотя я воюю с сеошниками, чтоб таких ситуаций избегать. Это сеошники обычно как к трагедии относятся к тому, что в урле будет лишнее слово. В Laravel нет механизма, насколько знаю, чтоб передать дальше по списку роутов, хотя сейчас может кто ещё придёт, подскажет.
     
  3. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Вот это ваша осн. проблема. Даже в фреймворках, которые вашу проблему решают на раз безо всякого трюкачества, рекомендуют использовать более простую тех. реализацию. Попробуйте только для одного из двух видов адресов использовать доп. префиксный компонент.
    --- Добавлено ---
    Или делайте общий обработчик и разруливайте внутри него, что есть что. Должен быть какой-то легкий способ это понять, например существовать отличительный признак в общей таблице городов/услуг :)
     
  4. MasterDmx

    MasterDmx Активный пользователь

    С нами с:
    17 авг 2014
    Сообщения:
    31
    Симпатии:
    0
    --- Добавлено ---
    Спасибо за ответ.

    Пока что думаю более менее подходящий костыль: сделать еще один контроллер и в его методе выполнять сравнение. Если город найден - запуск метода контроллера города, если нет - запуск метода контроллера услуг. Либо нарушить SRP и перенаправлять запрос прям из метода контроллера городов, сэкономив лишний запрос в бд
     
  5. MasterDmx

    MasterDmx Активный пользователь

    С нами с:
    17 авг 2014
    Сообщения:
    31
    Симпатии:
    0
    Спасибо за ответ. Именно из-за сеошников и приходится костылить)