Laravel 请求类 Reques-响应类 Response-中间件底层源码剖析

未匹配的标注

学习链接

xueyuanjun.com/post/9818
xueyuanjun.com/post/9820

Laravel 请求类 Request 剖析

Laravel 请求类 Request 剖析
Laravel请æ±åçå¾

  1. 捕获用户请求
  2. 获取请求对象
  3. 访问用户当前请求数据
  4. 访问持久化请求数据

注:所谓持久化的用户请求数据通常指的是用户上次请求输入的数据及用户 Cookie 数据。

响应类 Response 剖析

和 Laravel 请求对象类 Request 类似,代码底层有一个 Response 类用于表示发送给终端用户的应用响应,其中包含响应头、Cookie、响应内容、以及其它发送给终端用户浏览器用于渲染响应页面的东西。

Laravel 响应的底层实现

  1. Symfony\Component\HttpFoundation\Response 基类

  2. Symfony 实现了对状态码、HTTP协议版本、缓存、Etag、字符编码、响应实体等响应信息的封装

  3. 在 Illuminate\Http\Response 中,对 JSON 格式响应做了特别的优化

  4. 在 Laravel 请求的生命周期中,用户请求经过匹配路由处理后(通过控制器或匿名函数),就会返回相应的响应实例

  5. 响应头和响应内容的设置是在具体路由定义中实现

  6. 兜底处理,由路由器类 Illuminate\Routing\Router 的 toResponse 方法进行(自定义响应类的处理、返回的是数组、字符串、视图等非 Response 实例的处理)

  7. 请求处理完成,响应实例准备停当,发送给终端用户了,这段逻辑位于入口文件 public/index.php 中

以上,就是响应类 Response 实例化及返回给用户的底层实现原理

中间件底层原理

Laravel 请求类 Reques-响应类 Response-中间件底层源码剖析

  1. 从 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php 的 handle 方法开始
  2. 中间件的执行逻辑则是从该方法中的 sendRequestThroughRouter 开始
protected function sendRequestThroughRouter($request)
{
    $this->app->instance('request', $request);

    Facade::clearResolvedInstance('request');

    $this->bootstrap();

    return (new Pipeline($this->app))
                ->send($request)
                ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                ->then($this->dispatchToRouter());
}
  1. 构造 Illuminate\Routing\Pipeline 实例。

  2. 然后将当前请求实例 $request 赋值到 Pipeline$passable 属性。

  3. 如果应用启用中间件功能的话(默认启用),则将全局中间件数组 $middleware 赋值到 Pipeline$pipes 属性

  4. 接下来调用 dispatchToRouter 方法将请求转发给路由,该方法返回一个闭包函数,这个闭包函数将在处理完全局中间件逻辑后执行

  5. 接下来调用 Pipelinethen 方法:

  6. 这里首先调用 array_reduce 函数进行预处理,函数意思发送数组中的值到用户自定义函数,并返回一个字符串,类似于循环调用自定义函数。

  7. 遍历完所有全局中间件数组后,由于 carry 函数返回的还是闭包函数,所以直到此时都还没有执行任何中间件的 handle 方法,这段处理的意义是将所有全局中间件和路由处理通过统一的闭包函数进行迭代调用。最终返回的 $pipeline 是一个闭包函数

  8. 当执行完最后一个全局中间件 \App\Http\Middleware\TrustProxies::class,且请求未中断,控制流程进入到执行 $this->prepareDestination($destination) 返回的闭包函数,其中包含了应用到路由的中间件处理逻辑

  9. 最后,除了请求处理前执行的中间件,还有请求处理后执行的「终端中间件」,这些中间件在会在响应发送到客户端之后执行

中间件的实现实际上应用了管道设计模式,你可以参考这篇教程对其进行了解。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~