在Laravel 5.3中访问中间件中的路由URL参数

时间:2016-10-24 18:05:52

标签: laravel laravel-5 laravel-routing laravel-5.3 laravel-middleware

Laravel 5.1更新为Laravel 5.3后,我很难在中间件中访问路线网址参数。

这是我的路线档案:

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 让RouteMiddleware更新如下:

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,
    ];

Laravel 5.1 中,我能够从这样的中间件访问路由参数,我没有遇到任何麻烦:

public function handle($request, Closure $next)
{
        $appId = $request->route('apps');
        ...
}

但是,自升级到 Laravel 5.3 以来,上面的代码已经$appId作为null返回。我也尝试过访问像$appId = $request->apps这样的路由参数,这也没有用。

所以我随后更改了中间件以获取这样的url参数:

public function handle($request, Closure $next)
{
        $appId = $request->route()->parameters('apps');
        ...
}

由于改为上述内容,中间件似乎正在为第一条路由工作。但是,当我转到有2个参数的第二条路线时,我遇到了问题。出于某种原因,上面的代码失败了,当从中间件返回$request->route()->parameters('apps')时,我得到一个这样的数组:

Array
(
    [apps] => 1
    [colour] => green
)

为什么?为什么不返回$appId 1?我错过了什么或者是Laravel 5.3中的错误吗?我希望中间件只能从URL中访问appId参数,而不需要访问路由中的任何其他参数。有人可以帮我吗?

更新1:

我尝试更改中间件以获取如下参数:

$parameters = $request->route()->parameters();
$appId = $parameters['apps'];

在上面,我收到错误:

Undefined index: apps

但是当我print_r($parameters);时,输出是这样的:

Array
(
    [apps] => 1
    [day] => tuesday
)
[]

解决方案:

最后,我发现这种奇怪行为的原因是由于url中的参数名称。

以下资源路由生成的路径网址参数为app而不是apps。我不知道为什么:

Route::resource('apps/{apps}/houses', 'HouseController',
                        ['except' => ['index', 'create', 'edit']]);

以下路由生成路由url参数为apps

Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController@colourCheck');

由于这种奇怪的行为,一些路由返回null作为参数名apps,一些路由显示参数。在{app}和中间件中将所有路由参数重命名为routes/api.php后,中间件就开始按照应有的方式工作。

我不知道为什么资源路由正在创建app参数,但上面为我修复了错误,至少为此。

3 个答案:

答案 0 :(得分:2)

有两种方法可以访问中间件中的参数:

方法1 $request->route('parameter_name'); 这里parameter_name指的是我们称之为路线中的参数。

方法2 $request->route()->parameters(); 此方法将返回所有参数的数组。

答案 1 :(得分:1)

Resource Parameters Are Singular By Default

如果您想维护以前的行为而不是自动单一化资源路由参数,您可以对AppServiceProvider中的singularResourceParameters方法进行以下调用:

use Illuminate\Support\Facades\Route;

Route::singularResourceParameters(false);

答案 2 :(得分:0)

对我来说,这就是Laravel 6的解决方案。

在路由文件中,像这样添加->middleware()

Route::resource('orders', 'OrdersController')->middleware('roles:Admin,System');

现在检索中间件类中的参数:

public function handle($request, Closure $next, ...$roles)
{
     // now $roles contains: ['Admin, 'System']
}