3
votes

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.

3
The route() method should work in the middleware Laravel 5.3 to get a route param. Works fine for me.schellingerht
@schellingerht For me the route() method is always returning as null in Laravel 5.3. I have already added the middleware to RouteMiddleware in Kernel.php and its still null. I understand that Laravel 5.3 has changed the route file to api and web and the middleware I am using is for the api group, does that change anything? I dont understand why route() in middleware is showing null after updating.Neel

3 Answers

2
votes

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.

1
votes

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);
0
votes

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']
}