Laravel 响应 Response 剖析

1、从入口文件开始分析

Laravel的入口文件是 /public/index.php。

在index.php 中,处理请求的代码是:

  1. $response = $kernel->handle(
  2. $request = Illuminate\Http\Request::capture()
  3. );

Laravel 请求类 Request 剖析 说明了 $request 是如何获得的,下面将着重分析 handle 方法是如何处理请求的。

 

2、分析 $kernel 调用的 handle() 方法

它调用了 handle() 方法,在 App\Http\Kernel.php 中并没有 handle() 方法,因此它调用的其实是它的父类中的handle方法。

它的父类 handle() 方法是这样:

  1. public function handle($request)
  2. {
  3. try {
  4. // 启用对方法请求参数的支持
  5. $request->enableHttpMethodParameterOverride();
  6. // 通过中间件/路由器发送给定的请求
  7. $response = $this->sendRequestThroughRouter($request);
  8. } catch (Exception $e) {
  9. ...
  10. }
  11. $this->app['events']->dispatch(
  12. new RequestHandled($request, $response)
  13. );
  14. return $response;
  15. }

 
可以看到,解析请求获得响应的关键就在这一行代码:

  1. $response = $this->sendRequestThroughRouter($request);

这个方法是这样的:

  1. protected function sendRequestThroughRouter($request)
  2. {
  3. // 将现有实例注册为容器中的共享实例
  4. $this->app->instance('request', $request);
  5. // 清除已解析的外观实例
  6. Facade::clearResolvedInstance('request');
  7. // 在发送请求到路由之前,调用 bootstrap() 方法运用应用的启动类
  8. $this->bootstrap();
  9. // 以管道模式来处理 HTTP 请求
  10. return (new Pipeline($this->app))
  11. ->send($request)
  12. ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
  13. ->then($this->dispatchToRouter());

 
注:

  1. new Pipeline($this->app):
  2. // 创建 Illuminate\Routing\Pipeline 实例,并将应用实例 $this->app 赋值给 Illuminate\Pipeline\Pipeline 的 container 容器属性
  1. send($request):
  2. // 设置通过管道发送的对象,把request 赋值给 Illuminate\Pipeline\Pipeline 的 passable属性
  1. through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
  2. // 确定是否已为应用程序禁用中间件
  1. then($this->dispatchToRouter())
  2. // 获取路由调度程序回调,使用最终回调运行管道

 

 



Top