Is it possible to have a route parameter in the middle of a route string in Laravel?

Viewed 242

Like the title says: Is it possible to have a route parameter in the middle of a string in my route in Laravel 5.7?

My route is defined as so:

Route::get('/foos/foo-{bar}-baz', function () {
    return 'something';
}
->where('bar', '*+'), 
->middleware(['web', MyMiddleware::class]);

I am wanting to access this parameter in the MyMiddleware class but it always returns null, unless I define my route as '/foo/{bar}/baz'

I've tried a number of different regex combinations to no avail.

3 Answers

You could define it as (although the other answers seem to suggest you shouldn't need to)

Route::get("/foos/{foo-bar-baz}", function($fooBarBaz){
  return "something";
});

Essentially, anything after /foos/ would be available as $fooBarBaz. If $fooBarBaz contained something like "foo-bar-baz", you could simply explode it on - and access the second part of the parameter:

$parts = explode("-", $fooBarBaz);
// do something with $parts[1]

It should also be possible to regex-constrain the parameter to ensure it's in a specific format, such as foo-[a-zA-z]-baz, etc.

You have to define the regex of the bar parameter:

Route::get('/foos/foo-{bar}-baz', function () {
    return 'something';
})
->where('bar', '[a-z0-9-]+')
->middleware(['web', MyMiddleware::class]);

If I then visit /foos/foo-hello-world-baz on Chrome after, and perform a dd($request->bar); in my middleware, I receive the following output:

hello-world

For more information: https://laravel.com/docs/5.8/routing#parameters-regular-expression-constraints

You can do it exactly as you shown, I just tested and it works as expected.

First of all, register your middleware in the app\Http\Kernel.php file.

Then in the middleware handle method you can get the bar value as such:

$request->route('bar');

I used this for testing:

Route::get('/foos/foo-{bar}-baz', function($bar) {
   dd($bar);
})->middleware(['mym' => function($request, $handle) {
    dd($request->route('bar'), 'Test within middleware');
}]);

Given your middleware both returned the value for me again, can you try adding full namespace to the route:

->middleware(['web', \App\Http\Middleware\MyMiddleware::class]);
Related