参考:
https://www.jianshu.com/p/08b810b720d9
不能理解服务器容器的强烈推荐这位大佬写的
https://www.cnblogs.com/JdsyJ/p/12670497.html
今天学习下laravel的生命周期,首先说一下什么是生命周期,生命周期就是指一个请求到服务器,再被php处理,返回的这么一个过程。首先我们先说一下php生命周期,
1.模块初始化(MINIT),即调用 php.ini 中指明的扩展的初始化函数进行初始化工作,如 mysql 扩展。
2.请求初始化(RINIT),即初始化为执行本次脚本所需要的变量名称和变量值内容的符号表,如 $_SESSION变量。
3.执行该PHP脚本。
4.请求处理完成(Request Shutdown),按顺序调用各个模块的 RSHUTDOWN 方法,对每个变量调用 unset函数,如 unset $_SESSION 变量。
5.关闭模块(Module Shutdown) , PHP调用每个扩展的 MSHUTDOWN 方法,这是各个模块最后一次释放内存的机会。这意味着没有下一个请求了。
这个就看一下就行了,知道个大概,然后重头戏来了,我们laravel的生命周期
我们laravel的生命周期只占php的这三个阶段。让我们深入到代码层面
首先一个http请求来到的是index.php,如果是命令行请求到的就是artisan.php,这两个文件最大的区别就是在赋值$kernel的时候
//index.php
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
//artisan.php
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
可以看出,一个赋值的是http的内核,另一个赋值的是console的内核。
好,现在我们重点讲http请求的生命周期,也就是看index.php的代码
require __DIR__.'/../vendor/autoload.php';
首先是引入自动加载,这个不多说,这是composer的功能,有兴趣的朋友可以看看
https://segmentfault.com/a/1190000014948542
这里的自动加载引入了vender里面的各种类,之后我们只需要use使用就行了。
然后重点了来了,这里引入了app.php,生成了laravel的服务器容器。
$app = require_once __DIR__.'/../bootstrap/app.php';
服务容器的概念是laravel的核心概念,它其实就是一个注册了各种服务提供者的单例,它存活于这次请求的全部生命周期,它的作用是在开始时绑定服务器提供者,以便后面直接使用。至于为什么要有这么个服务容器,以及它是怎么实现了,请看我开头推荐的文章。这里我们重点说一下如何在容器中绑定服务提供者和容器的使用方法。
绑定方法有三种:
bind: 绑定一个实例,每次调用都返回一个新实例,相当每次都new一个新实例;
$this->app->bind('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});
singleton:绑定一个单例,每次调用都返回同一个实例(第一次调用先new),之后相当于=你第一次new出来的实现;
$this->app->singleton('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});
instance: 绑定一个已经初始化后的实例,相当于=一个实现;
$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\API', $api);
使用方法只有一个,make.make方法返回的就是你之前绑定的,根据你绑定的方法不同,返回不同的类型
$api = app()->make("HelpSpot\API");
现在我们进入app.php看看,这里可以看到之后用到的Illuminate\Contracts\Http\Kernel在这里被singleton绑定,绑定的类是App\Http\Kernel,这是laravel的http处理内核。
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
App\Http\Kernel内核继承自 Illuminate\Foundation\Http\Kernel 类, Illuminate\Foundation\Http\Kernel定义了一个 bootstrappers 数组,这个数组中的类在请求被执行前运行,这些 bootstrappers 配置了错误处理、日志、检测应用环境以及其它在请求被处理前需要执行的任务。
protected $bootstrappers = [
//注册系统环境配置 (.env)
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
//注册系统配置(config)
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
//注册日志配置
'Illuminate\Foundation\Bootstrap\ConfigureLogging',
//注册异常处理
'Illuminate\Foundation\Bootstrap\HandleExceptions',
//注册服务容器的门面,Facade 是个提供从容器访问对象的类。
'Illuminate\Foundation\Bootstrap\RegisterFacades',
//注册服务提供者
'Illuminate\Foundation\Bootstrap\RegisterProviders',
//注册服务提供者 `boot`
'Illuminate\Foundation\Bootstrap\BootProviders',
];
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
这里很明显就是生成了一个http的核心类。
今天先写到这,脑壳痛,明天再补~
++++++++++++++++++++++++++++++++++++++++++++++
各位,我水了,看到大佬的文章不想自己写了。推荐一个大佬的文章,直接分析源码的
Laravel学习笔记之Composer自动加载
https://segmentfault.com/a/1190000005085600
Laravel学习笔记之IoC Container实例化源码解析
https://segmentfault.com/a/1190000006909579