在 Laravel 5.3 的中间件中访问路由 URL 参数
Accessing Route URL Parameter in Middleware in Laravel 5.3
从 Laravel 5.1
更新到 Laravel 5.3
后,我很难访问中间件中的路由 URL 参数。
这是我的路由文件:
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 中的参数名称。
以下资源路由正在生成路由 url 参数作为 app
而不是 apps
。我不知道为什么:
Route::resource('apps/{apps}/houses', 'HouseController',
['except' => ['index', 'create', 'edit']]);
而以下路由正在生成路由 url 参数作为 apps
:
Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController@colourCheck');
由于这种奇怪的行为,一些路由返回参数名称 apps
的 null
和一些显示参数的地方。一旦我在 routes/api.php
和中间件中将所有路由参数重命名为 {app}
,中间件就开始正常工作了。
我不知道为什么资源路由将参数创建为 app
,但上面的内容为我修复了错误,至少现在是这样。
在中间件中访问参数有两种方式:
方法一
$request->route('parameter_name');
这里的parameter_name
就是我们在路由中调用的参数
方法二
$request->route()->parameters();
此方法将 return 一个包含所有参数的数组。
Resource Parameters Are Singular By Default
如果您想保持之前的行为而不是自动单数化资源路由参数,您可以对 AppServiceProvider 中的 singularResourceParameters 方法进行以下调用:
use Illuminate\Support\Facades\Route;
Route::singularResourceParameters(false);
对我来说,这是 Laravel 6 的解决方案。
在路由文件中添加 ->middleware()
,如下所示:
Route::resource('orders', 'OrdersController')->middleware('roles:Admin,System');
现在获取中间件中的参数class:
public function handle($request, Closure $next, ...$roles)
{
// now $roles contains: ['Admin, 'System']
}
从 Laravel 5.1
更新到 Laravel 5.3
后,我很难访问中间件中的路由 URL 参数。
这是我的路由文件:
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 中的参数名称。
以下资源路由正在生成路由 url 参数作为 app
而不是 apps
。我不知道为什么:
Route::resource('apps/{apps}/houses', 'HouseController',
['except' => ['index', 'create', 'edit']]);
而以下路由正在生成路由 url 参数作为 apps
:
Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController@colourCheck');
由于这种奇怪的行为,一些路由返回参数名称 apps
的 null
和一些显示参数的地方。一旦我在 routes/api.php
和中间件中将所有路由参数重命名为 {app}
,中间件就开始正常工作了。
我不知道为什么资源路由将参数创建为 app
,但上面的内容为我修复了错误,至少现在是这样。
在中间件中访问参数有两种方式:
方法一
$request->route('parameter_name');
这里的parameter_name
就是我们在路由中调用的参数
方法二
$request->route()->parameters();
此方法将 return 一个包含所有参数的数组。
Resource Parameters Are Singular By Default
如果您想保持之前的行为而不是自动单数化资源路由参数,您可以对 AppServiceProvider 中的 singularResourceParameters 方法进行以下调用:
use Illuminate\Support\Facades\Route;
Route::singularResourceParameters(false);
对我来说,这是 Laravel 6 的解决方案。
在路由文件中添加 ->middleware()
,如下所示:
Route::resource('orders', 'OrdersController')->middleware('roles:Admin,System');
现在获取中间件中的参数class:
public function handle($request, Closure $next, ...$roles)
{
// now $roles contains: ['Admin, 'System']
}