好记性不如烂笔头,学习php开发也不能懒,作笔记是一种学习的好习惯!
文章来自:www.haveyb.com/article/169
学习与交流:Laravel技术交流微信群
1、从入口文件开始分析
Laravel的入口文件是 /public/index.php。
在index.php 中,处理请求的代码是:
$response = $kernel->handle( | |
$request = Illuminate\Http\Request::capture() | |
); |
Laravel 请求类 Request 剖析 说明了 $request 是如何获得的,下面将着重分析 handle 方法是如何处理请求的。
2、分析 $kernel 调用的 handle() 方法
它调用了 handle() 方法,在 App\Http\Kernel.php 中并没有 handle() 方法,因此它调用的其实是它的父类中的handle方法。
它的父类 handle() 方法是这样:
public function handle($request) | |
{ | |
try { | |
// 启用对方法请求参数的支持 | |
$request->enableHttpMethodParameterOverride(); | |
// 通过中间件/路由器发送给定的请求 | |
$response = $this->sendRequestThroughRouter($request); | |
} catch (Exception $e) { | |
... | |
} | |
$this->app['events']->dispatch( | |
new RequestHandled($request, $response) | |
); | |
return $response; | |
} |
可以看到,解析请求获得响应的关键就在这一行代码:
$response = $this->sendRequestThroughRouter($request);
这个方法是这样的:
protected function sendRequestThroughRouter($request) | |
{ | |
// 将现有实例注册为容器中的共享实例 | |
$this->app->instance('request', $request); | |
// 清除已解析的外观实例 | |
Facade::clearResolvedInstance('request'); | |
// 在发送请求到路由之前,调用 bootstrap() 方法运用应用的启动类 | |
$this->bootstrap(); | |
// 以管道模式来处理 HTTP 请求 | |
return (new Pipeline($this->app)) | |
->send($request) | |
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) | |
->then($this->dispatchToRouter()); |
注:
new Pipeline($this->app): | |
// 创建 Illuminate\Routing\Pipeline 实例,并将应用实例 $this->app 赋值给 Illuminate\Pipeline\Pipeline 的 container 容器属性 | |
send($request): | |
// 设置通过管道发送的对象,把request 赋值给 Illuminate\Pipeline\Pipeline 的 passable属性 | |
through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) | |
// 确定是否已为应用程序禁用中间件 | |
then($this->dispatchToRouter()) | |
// 获取路由调度程序回调,使用最终回调运行管道 | |