Контроллер Laravel не получает правильный параметр из определения маршрута и вводит неправильную функцию контроллера

У меня определен этот маршрут:

Route::match(['get', 'post'], '/{class}/{function}/', [OldBackendController::class, 'apiV1']);

Если я сделаю этот запрос:

POST /api/v2_1/wishlist/archive

Laravel вводит int в OldBackendController, и значение переменной $class (в контроллере) следующее:

api/v2_1/wishlist

Почему? В контроллер он входить не должен, так как в запросе не 2 переменные, а 4.

Странно то, что если в контроллере я напечатаю значение $request->segments(), я получу все 4 сегмента:

Array
(
    [0] => api
    [1] => v2_1
    [2] => wishlist
    [3] => archive
)

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

Anuj Shrestha 17.03.2024 09:39

тем не менее маршрут определяет 2 переменные, а не 4

Giacomo M 17.03.2024 09:48

какой веб-сервер вы используете? как ты настроил красивые URL-адреса/переписывание URL-адресов?

lagbox 17.03.2024 13:50

Как вы упомянули в комментарии к ответу ниже, согласно документации/ должен быть автоматически исключен из любого параметра маршрута. Для ясности: как выглядит подпись вашего метода apiV1()? Маловероятно, но $class и $function могут быть зарезервированными словами. Пробовали ли вы использовать другие имена параметров?

Don't Panic 17.03.2024 17:57

@Don'tPanic public function apiV1(Request $request, string $class, string $function,)

Giacomo M 17.03.2024 22:50

Маршрут определен в routes/api.php? Есть ли для него какие-то префиксы или группы? Возможно ли, что другой маршрут совпадает и конфликтует, что-нибудь изменится, если вы временно удалите все остальные маршруты как в api.php, так и в web.php?

Don't Panic 26.03.2024 09:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
6
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш маршрут содержит две переменные, но, как вы видели, он попытается интерпретировать любой uri для этой переменной, насколько это возможно, и в конечном итоге вы разобьете uri /api/v2_1/wishlist/archive на две переменные api/v2_1/wishlist и archive.

Что вам нужно, так это указать маршруту, чтобы он не соответствовал символу / внутри переменных.

Route::match(['get', 'post'], '{class}/{function}', [OldBackendController::class, 'apiV1'])
    ->where('class', '[A-Za-z]+')->where('function', '[A-Za-z]+');

Вы можете адаптировать регулярное выражение, если ваша функция содержит _ или - или числовые символы.

Для получения дополнительной информации ознакомьтесь с Документацией.

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

Понятно. Меня беспокоит, почему я должен исключить символ / с регулярным выражением. Laravel должен автоматически исключить его.

Giacomo M 17.03.2024 12:36

@GiacomoM, в этом прелесть собственности «Dynamic». Там оно будет соответствовать чему угодно. Да, изначально это не очень понятно, и лучше всего никогда не использовать такой маршрут. Это вызовет множество проблем: этот маршрут также перехватит ваши маршруты 404 и вызовет ваш контроллер.

Anuj Shrestha 18.03.2024 06:30

@AnujShrestha Конечно, похоже, что именно это и происходит, но нет, они не должны там ничего совпадать, как уже указывал ОП. Из документации: «Компонент маршрутизации Laravel позволяет всем символам, кроме /, присутствовать в значениях параметров маршрута. Вы должны явно разрешить / быть частью вашего заполнителя, используя регулярное выражение условияwhere».

Don't Panic 18.03.2024 09:39

Да, я только что попробовал, и Laravel справляется с этим правильно и без использования регулярных выражений. он не пойдет туда, если путь маршрута больше или меньше 2. Понятия не имею, почему он не работает для OP.

Anuj Shrestha 18.03.2024 11:19

Другие вопросы по теме