Laravel进阶系列笔记--(一)Laravel生命周期

作者: 温新

分类: 【Laravel】

阅读: 1809

时间: 2021-08-09 12:39:06

作者:温新

时间:2021-07-04

hi,我是温新,一名PHPer。

了解完基础系列后,那么有必要来提高一个自己。Laravel太庞大了,基础系列仅仅只是它的一点点。Laravel进阶系列中的内容有许多我是没有用到也没有机会用到,不管用不用的到,那么现在一起重新学习吧。

序言

了解完基础系列后,是否有这样的疑问,Laravel的生命周期是怎么样的?中间件是如何拦截用户请求的?这都将在进阶系列中可以找到答案。

现在来安装一个全新的Laravel项目开启进阶系列的学习吧。

Laravel生命周期剖析

PHP生命周期有五个阶段,而Laravel运行中PHP的第三个生命周期内。

提出PHP生命周期只是为了更好的了解Laravel生命周期,这里不必纠结。

一切从index.php开始

Laravel请求从public/index.php开始,这也是Laravel生命周期的开始。先来看看index.php的内容:

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><?</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Http\Kernel</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Http\Request</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(51, 0, 170)">define</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'LARAVEL_START'</span>, <span style="box-sizing: border-box;color: rgb(51, 0, 170)">microtime</span>(<span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</span>));</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">if</span> (<span style="box-sizing: border-box;color: rgb(51, 0, 170)">file_exists</span>(<span style="box-sizing: border-box;color: rgb(34, 17, 153)">__DIR__</span>.<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'/../storage/framework/maintenance.php'</span>)) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">require</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">__DIR__</span>.<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'/../storage/framework/maintenance.php'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">require</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">__DIR__</span>.<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'/../vendor/autoload.php'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">require_once</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">__DIR__</span>.<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'/../bootstrap/app.php'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$kernel</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">make</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Kernel</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$response</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">tap</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$kernel</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">handle</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$request</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Request</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">capture</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">))<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">send</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$kernel</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">terminate</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$request</span>, <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$response</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span>

第一步:1、请求开始

用户请求到达index.php,会判断项目是否处于维护状态,若是处于维护状态,那么直接返回并终止请求向下走。

第二步:2、自动加载

这个过程会自动载项目所依赖的第三方组件包。

第三步:3、创建Laravel应用实例

app.php会创建应用实例。在创建应用实例的过程中会完成注册项目基础服务注册服务提供者注册目录路径等工作。

查看app.php内容:

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><?</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 3.1、创建应用实例</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Foundation\Application</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$_ENV</span>[<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'APP_BASE_PATH'</span>] <span style="box-sizing: border-box;color: rgb(152, 26, 26)">??</span> <span style="box-sizing: border-box;color: rgb(51, 0, 170)">dirname</span>(<span style="box-sizing: border-box;color: rgb(34, 17, 153)">__DIR__</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 3.2、完成内核绑定</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">singleton</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Http\Kernel</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Http\Kernel</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">singleton</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Console\Kernel</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Console\Kernel</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">singleton</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Debug\ExceptionHandler</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Exceptions\Handler</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span>;</span>

app.php完成两个部分的工作,分别是创建应用实例绑定内核到APP服务容器

3.1、查看实例化应用实例类

创建应用实例时会去实例化Illuminate\Foundation\Application类,在创建应用实例前会完成基础路径的注册基础服务提供者的注册、注册核心容器别名`的注册工作并将其绑定到应用容器。

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// Illuminate\Foundation\Application.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">__construct</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$basePath</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">null</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">if</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$basePath</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">setBasePath</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$basePath</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">registerBaseBindings</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">registerBaseServiceProviders</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">registerCoreContainerAliases</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

服务提供者在此阶段注册

3.2、内核绑定

Laravel根据请求类型的不同,将请求发送到HTTP内核或Console内核。不管是哪一个请求,其最终的作用都是接收一个HTTP请求,并返回一个响应结果。

HTTP内核继承自Illuminate\Foundation\Http\Kernel,在这个类中定义了一个$bootstrappers数组,这个数组中的类在请求被执行前运行。

HTTP内核还定义了中间件,所有请求都会经过HTTP中间件,Laravel拦截HTTP请求就是在这个地方进行拦截。

第四步:请求与响应

应用容器注册完成后,进入请求接收与响应阶段:

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 请求接收与响应</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$kernel</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">make</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Kernel</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$response</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">tap</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$kernel</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">handle</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$request</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Request</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">capture</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">))<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">send</span>();</span>

当请求走到$kernel = $app->make(Kernel::class);这时,看到它做了什么。

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">__construct</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Application</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Router</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$router</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">app</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$app</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">router</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$router</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">syncMiddlewareToRouter</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

内核在实例化时,构造函数中将中间件组注册到路由,注册完毕后就可以利用这些中间件对请求进行过滤。

4.1、处理HTTP请求

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 处理请求</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$response</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">tap</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$kernel</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">handle</span>(</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">  <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 创建请求实例</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$request</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Request</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">capture</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">))<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">send</span>();</span>

一旦应用被启动且所有服务提供者被注册,Request将会被交给路由进行分发,路由器将分发请求到路由或控制器,同时运行所有路由指定的中间件。

1-1-生命周期.jpg

我是温新

每天进步一点点,就一点点

请登录后再评论