[TOC]
![](https://box.kancloud.cn/51d527189c9841f2dc6ec55fb0234267_1890x956.png)
Laravel 的生命周期从`public\index.php`开始,从`public\index.php`结束。
~~~php
// 阶段一
require __DIR__.'/../bootstrap/autoload.php';
// 阶段二
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
// 阶段三
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
// 其它
$kernel->terminate($request, $response);
~~~
## **1. 加载项目依赖**
现代 PHP 依赖于 Composer 包管理器,入口文件通过引入由 Composer 包管理器自动生成的类加载程序,可以轻松注册并加载项目所依赖的第三方组件库。
所有组件的加载工作,仅需一行代码即可完成:
~~~php
require __DIR__.'/../vendor/autoload.php';
~~~
## **2. 创建 Laravel 应用实例**
创建应用实例(或服务容器),由位于 `bootstrap/app.php` 文件里的引导程序完成,创建服务容器的过程即为应用初始化的过程,项目初始化时包括:注册项目基础服务、注册项目服务器提供的别名、注册目录路径等在内的一些注册工作。
下面是`bootstrap/app.php`的代码,包含两个主要部分「创建应用实例」和「绑定内核至 APP 服务容器」:
~~~php
<?php
// 第一部分: 创建应用实例
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
// 第二部分: 完成内核绑定
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
return $app;
~~~
### **2.1 创建应用实例**
创建应用实例即实例化 `Illuminate\Foundation\Application` 这个服务容器(**APP容器**),其中包括:注册应用的基础路径并将路径绑定到 **APP容器**、注册基础服务提供者到**APP容器**、注册核心容器别名到**APP容器**
~~~php
/**
* Create a new Illuminate application instance.
*
* @param string|null $basePath
* @return void
*/
public function __construct($basePath = null)
{
if ($basePath) {
$this->setBasePath($basePath);
}
$this->registerBaseBindings();
$this->registerBaseServiceProviders();
$this->registerCoreContainerAliases();
}
~~~
### **2.2 内核绑定**
Laravel 会依据 HTTP 请求的运行环境的不同,将请求发送至相应的内核: **HTTP 内核** 或 **Console 内核**。无论 HTTP 内核还是 Console 内核,它们的作用都是是接收一个 HTTP 请求,随后返回一个响应。
## **3. 接收请求并响应**
~~~php
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
~~~
### **3.1 解析内核实例**
在第二阶段我们已经将 **HTTP 内核** 和 **Console 内核** 绑定到了 **APP 容器**,使用时通过 APP 容器 的 `make() ` 方法将内核解析出来,解析的过程就是内核实例化的过程。
~~~php
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
~~~
进一步挖掘 `Illuminate\Foundation\Http\Kernel` 内核的 `__construct(Illuminate\Contracts\Foundation\Application $app, \Illuminate\Routing\Router $router)` 构造方法,它接收 APP 容器 和 路由器 两个参数。
~~~php
/**
* Create a new HTTP kernel instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function __construct(Application $app, Router $router)
{
$this->app = $app;
$this->router = $router;
$this->syncMiddlewareToRouter();
}
~~~
在实例化内核时,构造函数内将在 HTTP 内核定义的「中间件组」注册到 **路由器**,注册完后就可以在实际处理 HTTP 请求前调用这些「中间件」实现 **过滤 请求**的目的。
~~~php
/**
* Sync the current state of the middleware to the router.
*
* @return void
*/
protected function syncMiddlewareToRouter()
{
$this->router->middlewarePriority = $this->middlewarePriority;
foreach ($this->middlewareGroups as $key => $middleware) {
$this->router->middlewareGroup($key, $middleware);
}
foreach ($this->routeMiddleware as $key => $middleware) {
$this->router->aliasMiddleware($key, $middleware);
}
}
/**
* Register a group of middleware.
*
* @param string $name
* @param array $middleware
* @return $this
*/
public function middlewareGroup($name, array $middleware)
{
$this->middlewareGroups[$name] = $middleware;
return $this;
}
/**
* Register a short-hand name for a middleware.
*
* @param string $name
* @param string $class
* @return $this
*/
public function aliasMiddleware($name, $class)
{
$this->middleware[$name] = $class;
return $this;
}
~~~
### **3.2 处理 HTTP 请求**
~~~
// 处理请求
$response = $kernel->handle(
// 创建请求实例
$request = Illuminate\Http\Request::capture()
);
~~~
* 创建请求实例
请求实例 `Illuminate\Http\Request` 的 `capture()` 方法内部通过 **Symfony** 实例创建一个 Laravel 请求实例。这样我们就可以获取到用户请求报文的相关信息
~~~
/**
* Create a new Illuminate HTTP request from server variables.
*
* @class Illuminate\Http\Request
* @return static
*/
public static function capture()
{
static::enableHttpMethodParameterOverride();
return static::createFromBase(SymfonyRequest::createFromGlobals());
}
/**
* Create an Illuminate request from a Symfony instance.
*
* @see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Illuminate\Http\Request
*/
public static function createFromBase(SymfonyRequest $request)
{
if ($request instanceof static) {
return $request;
}
$content = $request->content;
$request = (new static)->duplicate(
$request->query->all(), $request->request->all(), $request->attributes->all(),
$request->cookies->all(), $request->files->all(), $request->server->all()
);
$request->content = $content;
$request->request = $request->getInputSource();
return $request;
}
~~~
* 处理请求
请求处理发生在 HTTP 内核 的 `handle()` 方法内。
`Illuminate\Foundation\Http\kernel.php`
~~~
/**
* Handle an incoming HTTP request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function handle($request)
{
try {
$request->enableHttpMethodParameterOverride();
$response = $this->sendRequestThroughRouter($request);
} catch (Exception $e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
} catch (Throwable $e) {
$this->reportException($e = new FatalThrowableError($e));
$response = $this->renderException($request, $e);
}
$this->app['events']->dispatch(
new RequestHandled($request, $response)
);
return $response;
}
~~~
`handle()` 方法接收一个 HTTP 请求,并最终生成一个 HTTP 响应。
继续深入到处理 HTTP 请求的方法**$this->sendRequestThroughRouter($request)**内部。
~~~
/**
* Send the given request through the middleware / router.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
protected function sendRequestThroughRouter($request)
{
// 将 $request 实例注册到APP 容器供后续使用;
$this->app->instance('request', $request);
// 清除之前 $request 实例缓存
Facade::clearResolvedInstance('request');
// 启动「引导程序」
$this->bootstrap();
// 发送请求至路由
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
~~~
## **4. 发送响应**
发送响应由 `Illuminate\Http\Response` 父类 `Symfony\Component\HttpFoundation\Response` 中的 `send()` 方法完成。
~~~php
/**
* Sends HTTP headers and content.
*
* @return $this
*/
public function send()
{
// 发送响应头部信息
$this->sendHeaders();
// 发送报文主题
$this->sendContent();
if (\function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
static::closeOutputBuffers(0, true);
}
return $this;
}
~~~
## **5. 终止程序**
程序终止,完成终止中间件的调用
`Illuminate/Foundation/Http/Kernel.php`
~~~
/**
* Call the terminate method on any terminable middleware.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Response $response
* @return void
*/
public function terminate($request, $response)
{
$this->terminateMiddleware($request, $response);
$this->app->terminate();
}
/**
* Call the terminate method on any terminable middleware.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Response $response
* @return void
*/
protected function terminateMiddleware($request, $response)
{
$middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
$this->gatherRouteMiddleware($request),
$this->middleware
);
foreach ($middlewares as $middleware) {
if (! is_string($middleware)) {
continue;
}
[$name] = $this->parseMiddleware($middleware);
$instance = $this->app->make($name);
if (method_exists($instance, 'terminate')) {
$instance->terminate($request, $response);
}
}
}
~~~
*****
> 详见:https://learnku.com/articles/10421/depth-mining-of-laravel-life-cycle
- PHP
- PHP 核心架构
- PHP 生命周期
- PHP-FPM 详解
- PHP-FPM 配置优化
- PHP 命名空间和自动加载
- PHP 运行模式
- PHP 的 Buffer(缓冲区)
- php.ini 配置文件参数优化
- 常见面试题
- 常用函数
- 几种排序算法
- PHP - 框架
- Laravel
- Laravel 生命周期
- ThinkPHP
- MySQL
- 常见问题
- MySQL 索引
- 事务
- 锁机制
- Explain 使用分析
- MySQL 高性能优化规范
- UNION 与 UNION ALL
- MySQL报错:sql_mode=only_full_group_by
- MySQL 默认的 sql_mode 详解
- 正则表达式
- Redis
- Redis 知识
- 持久化
- 主从复制、哨兵、集群
- Redis 缓存击穿、穿透、雪崩
- Redis 分布式锁
- RedisBloom
- 网络
- 计算机网络模型
- TCP
- UDP
- HTTP
- HTTPS
- WebSocket
- 常见几种网络攻击方式
- Nginx
- 状态码
- 配置文件
- Nginx 代理+负载均衡
- Nginx 缓存
- Nginx 优化
- Nginx 配置 SSL 证书
- Linux
- 常用命令
- Vim 常用操作命令
- Supervisor 进程管理
- CentOS与Ubuntu系统区别
- Java
- 消息队列
- 运维
- RAID 磁盘阵列
- 逻辑分区管理 LVM
- 业务
- 标准通信接口设计
- 业务逻辑开发套路的三板斧
- 微信小程序登录流程
- 7种Web实时消息推送方案
- 用户签到
- 用户注册-短信验证码
- SQLServer 删除同一天用户重复签到
- 软件研发完整流程
- 前端
- Redux
- 其他
- 百度云盘大文件下载
- 日常报错记录
- GIT
- SSL certificate problem: unable to get local issuer certificate
- NPM
- reason: connect ECONNREFUSED 127.0.0.1:31181
- SVN
- SVN客户端无法连接SVN服务器,主机积极拒绝
- Python
- 基础
- pyecharts图表
- 对象
- 数据库
- PySpark
- 多线程
- 正则
- Hadoop
- 概述
- HDFS