Reputation: 9890
I am having a hard time accessing the Route URL Parameter in Middleware after updating from Laravel 5.1
to Laravel 5.3
.
Here is my route file:
Route::group(['middleware' => ['app.access']], function()
{
Route::resource('apps/{apps}/houses', 'HouseController',
['except' => ['index', 'create', 'edit']]);
Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController@colourCheck');
...
}
Kernel.php has RouteMiddleware updated like this:
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
// Added ones....
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
// Custom Middleware
'app.access' => \App\Http\Middleware\AppAccess::class,
];
In Laravel 5.1 and I was able to access route parameter from middleware like this and I had no trouble:
public function handle($request, Closure $next)
{
$appId = $request->route('apps');
...
}
But, since upgrading to Laravel 5.3, the above code started returned $appId
as null
. I also tried accessing route parameter like $appId = $request->apps
and this was not working as well.
So I then changed the Middleware to get the url parameter like this:
public function handle($request, Closure $next)
{
$appId = $request->route()->parameters('apps');
...
}
Since changing to the above, the middleware seems to be working for the first route. But then, I am having problem when going to the second route that has 2 parameters. For some reason, the above code fails and when returning $request->route()->parameters('apps')
from middleware, I am getting an array like this:
Array
(
[apps] => 1
[colour] => green
)
Why is that? Why is it not returning just the $appId
which is 1
? Am I missing something or is it a bug in Laravel 5.3? I want the Middleware to access only the appId
parameter from the url and nothing else from the route. Can someone help me here please?
Update 1:
I tried changing the Middleware to get parameter like this:
$parameters = $request->route()->parameters();
$appId = $parameters['apps'];
In the above, I am getting the error:
Undefined index: apps
But when I print_r($parameters);
, the output is like this:
Array
(
[apps] => 1
[day] => tuesday
)
[]
Solution:
In the end, I found out the reason for this odd behaviour was due the parameter name in the url.
The following resources routes were generating route url parameter as app
instead of apps
. I dont know why though:
Route::resource('apps/{apps}/houses', 'HouseController',
['except' => ['index', 'create', 'edit']]);
Whereas the following routes were generating route url parameter as apps
:
Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController@colourCheck');
Due to this odd behaviour, some routes were returning null
for the parameter name apps
and some where showing the parameter. Once I renamed all route parameters to {app}
in the routes/api.php
and Middleware, the Middleware started working the way it should.
I don't know why the resource routes were creating the parameter as app
, but the above fixed the error for me, atleast for now.
Upvotes: 4
Views: 2960
Reputation: 3155
For me, this was the solution for Laravel 6.
In the routes file add ->middleware()
like this:
Route::resource('orders', 'OrdersController')->middleware('roles:Admin,System');
Now to retrieve the parameters in the middleware class:
public function handle($request, Closure $next, ...$roles)
{
// now $roles contains: ['Admin, 'System']
}
Upvotes: 0
Reputation: 3800
Resource Parameters Are Singular By Default
If you would like to maintain the previous behavior instead of automatically singularizing resource route parameters, you may make the following call to the singularResourceParameters method in your AppServiceProvider:
use Illuminate\Support\Facades\Route;
Route::singularResourceParameters(false);
Upvotes: 1
Reputation: 17708
There are two ways for accessing parameters in a middleware:
Method 1
$request->route('parameter_name');
Here parameter_name
refers to what we called the parameter in the route.
Method 2
$request->route()->parameters();
This method will return an array of all the parameters.
Upvotes: 3