今天我们将讨论如何在中间件中使用路由参数,这个任务可能会出现在您的工作流程中。
什么是中间件?
中间件只是包装应用程序的请求。可以这样想,当向您的应用程序发出请求时,有处理请求的代码,但是如果您希望在处理请求的代码运行之前或之后发生某些事情,则可以放入中间件。
Laravel 附带了一些用于维护、身份验证和 CSRF 保护的内置中间件,它们都可以在Laravel 项目文件夹内的app/Http/Middleware目录中找到。
Laravel 路由参数
Laravel 路由位于app/Http/routes.php文件中。一个路由通常有 URL 路径,以及一个处理函数回调,通常是某个控制器中编写的函数。
// Inline function to handle the route
Route::get('/', function () {
return view('welcome');
});
// Controller function to handle the route
Route::get('/profile', 'ProfileController@index');
路由中提供的参数通常用花括号注释。例如,要将 name 参数传递给路由,它看起来像这样。
Route::get('/params/{name}', function ($name) {
return $name
});
按照惯例,Controller 函数根据提供的参数接受参数。
访问路由参数
然而,访问中间件中的参数并不是那么直接。首先让我们创建一个称为DumpMiddleware
转储路由中提供的参数的中间件。
php artisan make:middleware DumpMiddleware
文件app/Http/Middlware/DumpMiddleware.php已创建。
方法一: $request->route('parameter_name')
我们可以通过两种方式访问路由参数。一种方法是使用$request->route('parameter_name')
., whereparameter_name
指的是我们在路由中调用的参数。在app/Http/Middleware/DumpMiddleware.php文件中创建的 DumpMiddleware 类中的 handle 方法中。
public function handle($request, Closure $next)
{
dd($request->route('parameter_name'));
return $next($request);
}
要查看中间件的运行情况,让我们将其添加到路由中。快速创建我们上面显示的路由,并在app/Http/routes.php文件中添加中间件。
Route::get('/params/{name}', [
'middleware' => 'App\Http\Middleware\DumpMiddleware',
function () {
return view('welcome');
}]);
我们需要中间件的完整命名空间,因为我们还没有让 Laravel 知道我们的新中间件。为此,我们将它添加到App\Http\Kernel.php文件中,作为$routeMiddleware
类属性的一部分。
protected $routeMiddleware = [
// Middlewares commented out for brevity
'DumpMiddleware' => \App\Http\Middleware\DumpMiddleware::class,
];
然后,您可以将路由中的中间件更新为'middleware' => 'DumpMiddleware',
.
php artisan serve
在终端上运行并打开http://localhost:8000/params/scotch
. 您应该会在浏览器中看到scotch转储。
方法二: $request->route()->paremeters()
在中间件中访问 Route 参数的另一种方法是获取所有参数。想象一下你有这样的路线/params/{id}/{category}/{name}
。所有的路由参数通常保存在一个数组中,在中间件中可以通过$request->route()->parameters()
. 如果我们将路线更新为上述路线,
Route::get('/params/{id}/{category}/{name}', [
'middleware' => DumpMiddleware',
function () {
return view('welcome');
}]);
并将中间件的句柄方法更新为,
public function handle($request, Closure $next)
{
dd($request->route()->parameters());
return $next($request);
}
Going tohttp://localhost:8000/params/23/scotch/school
应该将浏览器中的参数作为数组转储,以参数名称作为键,以及作为值传递的内容。
为什么要在中间件中访问路由参数?
在中间件中访问路由参数的示例用法是给定路由执行不同的操作。例如,假设您有一条返回用户个人资料的路由,/{username}
. 例如,要转到 Scotch 的个人资料,可以转到http://localhost:8000/scotch
。
但是,此应用程序可能有一些不一定属于个人资料的路线。喜欢常见问题,或支持,或帮助。在这种情况下,通常建议在查找配置文件的路由之前定义这些路由。
应用程序/http/routes.php
Route::get('/faq', function() {
return view('faq');
});
Route::get('/help', function() {
return view('help');
});
Route::get('/support', function() {
return view('support');
});
// Route that handles profile comes last
Route::get('/{username}', function() {
return view('profile');
});
然而,对于中间件,我们需要做的就是检查一个值是否在定义的数组中并重定向。
应用程序/Http/routes.php
Route::get('/{username}', [
'middleware' => 'ProfileMiddleware',
function () {
return view('welcome');
}]);
然后在配置文件中间件中,我们将其添加到句柄函数中。
<?php
namespace App\Http\Middleware;
use Closure;
// Add Response namespace
use Illuminate\Http\Response;
class ProfileMiddleware
{
public function handle($request, Closure $next)
{
$routes = ["faq", "support", "help"];
$route = $request->route('username');
// Redirect to custom page if it doesn't relate to a profile
if (in_array($route, $routes)) {
return new Response(view($route));
}
return $next($request);
}
}
我们只是检查参数是否在给定的数组中,并基于它返回一个视图。如果我们有任何其他不需要配置文件的关键字,我们需要做的就是将它们添加到这个数组中。更干净,对吧?