Search code examples
laravellaravel-5laravel-routinglaravel-5.3laravel-middleware

Accessing Route URL Parameter in Middleware in Laravel 5.3


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.


Solution

  • 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.