Search code examples
phplaravellaravel-10

Laravel controller does not get correct parameter from route definition, and enters in the wrong controller function


I have this route defined:

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

If I do this request:

POST /api/v2_1/wishlist/archive

Laravel enters int the OldBackendController, and the value of $class variable (in the controller), is this:

api/v2_1/wishlist

Why? It shouldn't enter in the controller, cause the request does not contains 2 variables, but 4.

The strange thing is if in the controller I print $request->segments() value, I get all 4 segment:

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

Solution

  • You route contain two variables but as you saw, it will try to interpret any uri to those variable as possible as it can and you end up having the uri /api/v2_1/wishlist/archive broken down to two variables api/v2_1/wishlist and archive.

    What you need is to tell the route to not match the character / inside the variables

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

    You can adapt the regex if your function contain _ or - or numeric characters.

    For more information check the Documentation

    note: In all cases, you should put this route at the end of your route file as it will match with anything that has two uri segments and give you a headache in the future.