Tp5.2 定义中间件时的Closure $next怎么理解

本文介绍了TP5.2框架中定义中间件的过程,特别是`$next`闭包的使用。在中间件的`handle`方法中,`$next($request)`用于传递请求到下一个中间件或控制器。通过`App()->run()`触发中间件调度,`thinkMiddleware::dispatch`方法处理中间件队列,利用`call_user_func_array`执行回调函数,将`$next`作为参数传入,确保请求的逐层处理。

定义中间件的步骤

默认中间件存放位置 

'default_namespace' => 'app\\http\\middleware\\',

创建一个 Check中间件 

<?php

namespace app\http\middleware;

class Check
{
    public function handle($request, \Closure $next)
    {
        if ($request->param('name') == 'think') {
            return redirect('index/think');
        }

        return $next($request);
    }
}

中间件的入口执行方法必须是handle方法,而且第一个参数是Request对象,第二个参数是一个闭包。

如何理解$next($request)

1. new App())->run() 中 执行到了中间件调度方法

$response = $this->middleware->dispatch($this->request);

2.在 think\Middleware.php 中可以看到dispatch 方法 调用了

call_user_func($this->resolve($type), $request);


第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。

3. resolve() 是一个回调函数 其中执行了$middleware = array_shift($this->queue[$type]);删除并得到队列中的第一个元素 。下一步list($call, $param) = $middleware;

下面值关键的一步

$response = call_user_func_array(array('app\http\middleware\Check','handle'), [$request, $this->resolve(), $param]);

call_user_func_array ( callable $callback , array $param_arr )
把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。
这里的$this->resolve() 对应的就是  handle($request, \Closure $next) 的 \Closure $next 这个参数。


tp5.2中resolve() 方法如下

protected function resolve(string $type = 'route')
{
        return function (Request $request) use ($type) {
            $middleware = array_shift($this->queue[$type]);
            if (null === $middleware) {
                throw new InvalidArgumentException('The queue was exhausted, with no response returned');
            }
            list($call, $param) = $middleware;
            try {
                $response = call_user_func_array($call, [$request, $this->resolve(), $param]);
            } catch (HttpResponseException $exception) {
                $response = $exception->getResponse();
            }
            if (!$response instanceof Response) {
                throw new LogicException('The middleware must return Response instance');
            }
            return $response;
        };
}

 

### Laravel 自定义中间件 `AuthenticateLogin` 的代码逻辑与功能解析 在 Laravel 框架中,`AuthenticateLogin` 是一种用于验证用户身份的自定义中间件。它的核心作用在于拦截未授权的请求,并确保只有已登录的用户才能访问受保护的资源。 #### 中间件的核心逻辑 以下是 `AuthenticateLogin` 中间件的关键部分及其解释: ```php <?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class AuthenticateLogin { /** * 处理传入的请求. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // 检查用户是否已经登录 if (!Auth::check()) { // 如果用户未登录,则重定向到登录页面,并附带错误消息 return redirect('login')->with('error', '您尚未登录!'); } // 用户已登录的情况下继续执行后续操作 return $next($request); } } ``` - **`Auth::check()`**: 此方法用于判断当前是否有用户处于登录状态。如果返回值为 `false`,则表示用户未登录[^1]。 - **`redirect('login')`**: 当检测到用户未登录,系统会将请求重定向至指定的登录页面。这里假设登录页路径为 `/login`[^2]。 - **`$next($request)`**: 若用户已成功登录,则调用 `$next($request)` 将请求传递给下一个处理环节(可能是控制器或其他中间件)。这是确保请求正常流转的重要一步[^3]。 #### 注册与绑定中间件 为了让应用程序识别并使用新的中间件,需要对其进行注册。具体步骤如下: ##### 修改 `Kernel.php` 编辑位于 `app/Http/Kernel.php` 的文件,在其中添加一条映射关系: ```php protected $routeMiddleware = [ // 其他中间件... 'auth.login' => \App\Http\Middleware\AuthenticateLogin::class, ]; ``` 此处新增键 `'auth.login'` 对应刚刚创建好的类实例位置[^4]。 ##### 应用中间件 最后一步是在实际业务场景中运用该中间件。可以选择两种方式之一实施控制——要么直接附加于单一路由之上;要么统一应用于整个控制器内部的所有动作之中。 ###### 路由层面 对于特定 URL 设置防护屏障: ```php Route::get('/admin/dashboard', function () { return view('admin.dashboard'); })->middleware('auth.login'); ``` ###### 控制器层面 全局约束某个类别下的所有接口均需经过认证校验: ```php public function __construct() { $this->middleware('auth.login'); } ``` --- ### 扩展讨论:深入理解中间件的工作机制 Laravel 的 HTTP 请求生命周期依赖于管道模式(Pipeline Pattern),即每一个进入系统的请求都会被依次送入一系列预设好的处理器链条当中逐一加工改造后再送出响应结果[^5]。这种设计理念赋予了开发者极大的灵活性去定制自己的工作流。 当提到像 `AuthenticateLogin` 这样的安全组件,实际上它只是众多可能插槽里的其中一个节点而已。每当有新访客尝试触碰那些受到限制的内容区块前,先得经历这一层筛选过滤网筛除掉不符合条件者。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值