控制器之中间件Middleware
中间件有什么用
Laravel中间件提供一个方便的机制来过滤进入应用程序的HTTP请求。
用一个示例来说明
需求:有一个活动,在指定日期后开始,如果活动没开始,那么就只能访问宣传页面
这个需求涉及到的知识点:
- 新建中间件
- 注册中间件
- 使用中间件
- 中间件的前置和后置操作
新建控制器中的方法
在app/Http/Controllers/StudentController.php中:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StudentController extends Controller
{
// 活动的宣传页面
public function activity0()
{
return '活动快要开始了 敬请期待';
}
// 活动的宣传页面1
public function activity1()
{
return '活动进行中,谢谢您的参与1';
}
// 活动的宣传页面2
public function activity2()
{
return '活动进行中,谢谢您的参与2';
}
}
创建并注册中间件
创建中间件,在app/Http/Middleware文件夹中,创建Activity.php (注意首字母大写):
// 首先写命名空间 与目录一致
namespace App\Http\Middleware;
// 这里加了 就不用在参数中使用\Closure $next了
use Closure;
class Activity{
public function handle($request, Closure $next)
{
if (time() < strtotime('2021-07-05')) {
// 如果日期小于7月8日那么跳转到活动未开始页面
return redirect('activity0');
}
// next是一个方法,执行的请求的方法
return $next($request);
}
}
这里注意,handle中的$request,Closure$next是固定写法,如果不在上面use Closure,那么则需要如下写法:
public function handle($request, \Closure $next) { ... }
注册路由中间件,在app/Kernel.php中的protected $routeMiddleware下:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
...
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
// 注册中间件,并引入中间件文件的路径
'activity' => \App\Http\Middleware\Activity::class,
];
注意,高版本的PHP可能不支持::class写法,请选择laravel对应版本的PHP。
应用中间件,在app/routes.php中:
// 宣传页面,未举行活动的页面放到外面
Route::any('activity0', [
'uses' => 'StudentController@activity0'
]);
// 活动页面,只有活动页面需要接受中间件的验证。
// 使用中间件, 将需要验证的页面拿到中间件里面,不需要验证的则放到外面即可
Route::group(['middleware' => ['activity']], function () {
Route::any('activity1', [
'uses' => 'StudentController@activity1'
]);
Route::any('activity2', [
'uses' => 'StudentController@activity2'
]);
});
创建路由组,并在路由组中使用新创建的activity中间件。
这时,访问localhost/laravel/public/activity1会根据当前时间判断,如果早于2021-07-05,那么会跳转到activity0这个路由上;如果晚于2021-07-05,那么会直接执行控制器中的activity1方法,从而打印出方法中的字符串。
中间件的前置与后置
前置和后置是根据中间件的逻辑,是在请求执行前还是请求执行后执行。
- 前置操作就是在加载页面(加载控制器)之前做的操作;
- 后置就是逻辑在请求后执行,是在加载页面(加载控制器)之后做的操作。
向(二)中的例子,就是一个前置操作,在请求$next($request)之前进行。
$next($request)是一个请求,返回的是响应。实际就是执行了(比如示例中的控制器中的activity1这个方法)
public function handle($request, Closure $next)
{
$response = $next($request);
dd($response);
echo '我是后置操作';
}
使用var_dump打印$response的结果:
object(Illuminate\Http\Response) // 可见打印出来的是一个对象
而在请求执行后,打印了“后置操作”。如果echo请求:
/* 结果:HTTP/1.1 200 OK Cache-Control: no-cache Content-Type: text/html; charset=UTF-8
活动进行中,谢谢您的参与2我是后置操作
*/
echo ($response);