4

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.

2
  • The route() method should work in the middleware Laravel 5.3 to get a route param. Works fine for me. Commented Oct 24, 2016 at 19:23
  • @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. Commented Oct 25, 2016 at 9:40

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

5 Comments

When I tried the Method 1, I am getting it as null. In method 2, I only want to get the appId so when I add it as $request->route()->parameters('apps'), I am still getting the array of all parameters when the url has multiple parameter like the example in my OP.
For Method 1 - Make sure you are using the same name for parameter_name for what you called it in route.php. As for Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController@colourCheck'); you will call it as $request->route('apps') or $request->route('colour'). And $request->route()->parameters(); doesn't accecpt any parameters, it always returns an array.
Thanks for your reply @AmitGupta I did use the route() method as $request->route('apps'), but it is returning as null. apps is the parameter name called in routes/api.php. I have also added the middleware to RouteMiddleware in Kernel.php but still its returned as null.
I tried the second method to get the appId parameter from the array but that is not working neither. I have updated my post with what I tried and what output I am getting when I use print_r.
Have updating my post with the solution that worked for now. Thanks for your answer.
1

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

1 Comment

ah... thanks @HarryBosh for the link. Now it makes sense on why the route parameter is singularised in 5.3 only.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.