laravel框架的生命周期解析
一阶段:入口文件(public/index.php)
- require autoload.php 加载 Composer 的自动加载器,使得所有命名空间的类都能被自动加载
- $app->make() 从服务容器中解析 HTTP Kernel 实例
第二阶段:应用启动(bootstrap/app.php)
// 1. 创建应用容器实例
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
// 2. 绑定核心接口到容器
$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
);
// 3. 返回应用实例
return $app;
底层逻辑:
- new Illuminate\Foundation\Application() 创建服务容器,这是 Laravel 的核心
- singleton() 将接口绑定到具体实现,确保整个应用生命周期只有一个实例
第三阶段:HTTP 内核处理(app/Http/Kernel.php)
你的项目中的 Kernel 定义了三层中间件:
// 1. 全局中间件 - 每个请求都会经过
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
// 2. 中间件组 - 根据路由分组应用
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\AdminOperationLog::class,
],
'api' => [
'throttle:500,1',
'bindings',
],
];
// 3. 路由中间件 - 单个路由可以使用
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'throttle' => \App\Http\Middleware\ThrottleRequests::class,
// ...
];
底层处理流程(洋葱模型):
请求进入
↓
全局中间件 1 (CheckForMaintenanceMode)
↓
中间件组 (web/api/vue)
├─ EncryptCookies
├─ AddQueuedCookiesToResponse
├─ StartSession
├─ ShareErrorsFromSession
├─ VerifyCsrfToken
├─ SubstituteBindings
└─ AdminOperationLog
↓
路由中间件 (如果有)
↓
控制器方法执行
↓
返回响应(反向经过所有中间件)
第四阶段:服务提供者注册和启动
根据你的 config/app.php,Laravel 会按顺序加载所有服务提供者:
'providers' => [
// Laravel 框架服务提供者
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
// ... 更多框架提供者
// 应用服务提供者
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
// ...
];
// 伪代码展示底层逻辑
foreach ($providers as $provider) {
// 1. 实例化服务提供者
$providerInstance = new $provider($app);
// 2. 调用 register() 方法 - 绑定服务到容器
$providerInstance->register();
}
// 所有 register() 完成后,再调用所有 boot() 方法
foreach ($providers as $provider) {
// 3. 调用 boot() 方法 - 初始化服务
$providerInstance->boot();
}
为什么分两步?
- register() 阶段:绑定服务,不依赖其他服务
- boot() 阶段:初始化服务,可以依赖其他已注册的服务
第五阶段:路由匹配和请求处理
当请求到达时,Laravel 的底层路由处理流程:
// 简化的底层逻辑
class Router {
public function dispatch(Request $request) {
// 1. 根据 HTTP 方法和 URI 匹配路由
$route = $this->matchRoute($request);
// 2. 如果没有匹配到路由,返回 404
if (!$route) {
throw new NotFoundHttpException();
}
// 3. 获取路由对应的控制器和方法
$controller = $route->getController();
$method = $route->getMethod();
// 4. 解析依赖并调用控制器方法
return $this->callController($controller, $method, $request);
}
private function callController($controller, $method, $request) {
// 使用容器解析控制器的依赖
$instance = $this->container->make($controller);
// 调用方法,容器会自动注入依赖
return $instance->$method($request);
}
}
第六阶段:你的控制器执行(IndexController)
以你的 IndexController::index() 为例:
public function index(Request $request) {
// 1. 容器自动注入 Request 对象
$userID = $request->userLogin->user_id;
// 2. 分发异步任务到队列
dispatch(new UpdatePinyin($userID));
// 3. 业务逻辑处理
$type = (int)$request->input('type', 1);
// 4. 数据库查询
$list = BookReadStatistical::getReadDateList($userID, $startDate);
// 5. 返回 JSON 响应
return $this->formatJsonResult($returnData, self::CODE_SUCCESS, '成功');
}
底层依赖注入逻辑:
// 容器如何解析 Request 参数
class Container {
public function make($class) {
// 1. 获取类的构造函数参数
$reflector = new ReflectionClass($class);
$constructor = $reflector->getConstructor();
// 2. 遍历参数,递归解析依赖
$parameters = [];
foreach ($constructor->getParameters() as $param) {
$paramClass = $param->getClass();
// 3. 如果参数有类型提示,从容器中解析
if ($paramClass) {
$parameters[] = $this->make($paramClass->name);
}
}
// 4. 创建实例并注入依赖
return new $class(...$parameters);
}
}
第七阶段:中间件的洋葱模型
中间件的执行是通过 Pipeline(管道)实现的:
// 简化的 Pipeline 实现
class Pipeline {
public function send($request) {
return $this->passThrough($request);
}
private function passThrough($request) {
// 从最后一个中间件开始,向前包装
$next = function($request) {
return $this->controller->handle($request);
};
// 从后向前遍历中间件
foreach (array_reverse($this->middleware) as $middleware) {
$next = function($request) use ($middleware, $next) {
// 执行中间件的 handle 方法
return $middleware->handle($request, $next);
};
}
// 执行第一个中间件
return $next($request);
}
}
实际执行顺序:
请求 → 中间件1 → 中间件2 → 中间件3 → 控制器 → 中间件3 → 中间件2 → 中间件1 → 响应
第八阶段:响应发送和终止
// public/index.php 的最后部分
$response->send(); // 发送 HTTP 响应头和内容
$kernel->terminate($request, $response); // 执行终止回调
底层逻辑:
class Response {
public function send() {
// 1. 发送响应头
http_response_code($this->statusCode);
foreach ($this->headers as $name => $value) {
header("$name: $value");
}
// 2. 发送响应体
echo $this->content;
}
}
class Kernel {
public function terminate($request, $response) {
// 1. 执行所有注册的终止回调
foreach ($this->terminatingCallbacks as $callback) {
$callback($request, $response);
}
// 2. 关闭数据库连接
// 3. 清理资源
}
}
完整的生命周期流程图
1. public/index.php
↓
2. bootstrap/autoload.php (Composer 自动加载)
↓
3. bootstrap/app.php (创建容器,绑定核心接口)
↓
4. 获取 HTTP Kernel: $app->make(Kernel::class)
↓
5. 捕获请求: Request::capture()
↓
6. $kernel->handle($request)
├─ 加载所有服务提供者的 register() 方法
├─ 加载所有服务提供者的 boot() 方法
├─ 执行全局中间件
├─ 匹配路由
├─ 执行路由中间件组
├─ 执行路由特定中间件
├─ 解析控制器依赖
├─ 执行控制器方法
└─ 返回响应
↓
7. $response->send() (发送响应)
↓
8. $kernel->terminate() (执行终止回调)
关键的底层概念
1. 服务容器(IoC Container)
- 所有对象都通过容器创建和管理
- 支持自动依赖注入
- 支持单例和瞬时实例
2. 服务提供者(Service Provider)
- 应用的启动和配置中心
- register() 绑定服务
- boot() 初始化服务
3. 中间件(Middleware)
- 洋葱模型执行
- 可以在请求前后处理
- 支持全局、分组、路由级别
4. 依赖注入(Dependency Injection)
- 通过反射获取参数类型
- 自动从容器中解析依赖
- 支持构造函数注入、方法注入
这就是 Laravel 框架的完整底层逻辑。核心思想是通过服务容器管理所有对象,通过服务提供者组织启动逻辑,通过中间件处理请求,通过依赖注入解耦代码。

浙公网安备 33010602011771号