找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 28|回复: 2

Thinkphp6底层操作逻辑

[复制链接]

86

主题

84

回帖

728

积分

管理员

积分
728
发表于 2025-9-1 11:11:29 | 显示全部楼层 |阅读模式
1. public/index.php          → 入口文件      
2. require '../vendor/autoload.php' → Composer 自动加载      
3. (new App())->run()        → 启动应用      
4. 初始化容器、环境、配置      
5. 加载服务提供者(Service Provider)      
6. 路由解析(Route Dispatch)      
7. 中间件执行(Middleware Stack)      
8. 控制器方法调用(Controller Action)     
9. 生成响应(Response
10. 发送响应并结束

86

主题

84

回帖

728

积分

管理员

积分
728
 楼主| 发表于 2025-9-1 11:14:02 | 显示全部楼层
总结:TP6 请求生命周期核心要点
阶段        核心机制
启动        Composer 自动加载 + 容器初始化
初始化        环境变量 + 配置加载 + 服务提供者注册
路由        路由规则解析 → 生成 Dispatch
中间件        洋葱模型,闭包嵌套执行
控制器        容器创建实例,自动依赖注入
响应        自动包装 Response,发送输出

86

主题

84

回帖

728

积分

管理员

积分
728
 楼主| 发表于 2025-9-1 11:14:57 | 显示全部楼层
详细源码流程分析(基于 TP6.0+ 源码)
1. 入口文件:public/index.php
<?php
// 定义应用目录
define('APP_PATH', __DIR__ . '/../app/');

// 加载 Composer 自动加载
require __DIR__ . '/../vendor/autoload.php';

// 执行应用
(new \think\App())->run()->send();
✅ 这是所有请求的统一入口,遵循“单一入口”原则。

2. new App():初始化应用容器
文件:thinkphp/library/think/App.php
public function __construct(string $rootPath = '')
{
    $this->instance('app', $this);
    $this->instance('think\Container', $this);

    $this->rootPath = $rootPath ?: dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR;
    $this->bind([
        // 绑定核心类
        'app'           => self::class,
        'container'     => Container::class,
    ]);
}
关键动作:

创建服务容器(Container),自身也注册为单例。
设置项目根目录。
绑定核心类到容器。
3. $app->run():启动应用
public function run()
{
    try {
        // 初始化基础环境
        $this->initialize();

        // 路由调度
        $dispatch = $this->routeCheck();

        // 执行调度(进入中间件和控制器)
        $data = $this->dispatch($dispatch);

    } catch (Throwable $e) {
        $data = $this->render($e);
    }

    // 包装为 Response 对象
    return $this->response($data);
}
4. $this->initialize():初始化阶段
protected function initialize()
{
    // 设置错误处理
    $this->setDebugMode();
    $this->setExceptionHandler();

    // 加载环境变量(.env)
    $this->loadEnv();

    // 注册服务提供者
    $this->registerServiceProviders();

    // 加载配置文件(config/*.php)
    $this->loadConfigFiles();

    // 注册核心门面
    $this->registerFacades();
}
关键动作:
加载 .env 环境变量
注册服务提供者(ServiceProvider)
遍历 config/app.php 中的 providers,调用每个服务的 register() 方法,将服务绑定到容器。
php
深色版本
'providers' => [
    think\service\CacheService::class,
    think\service\EventService::class,
]
加载配置文件:将 config/*.php 文件合并到 Config 实例中。
注册门面(Facade):为 Cache, Log 等提供静态代理。
5. $this->routeCheck():路由解析
protected function routeCheck()
{
    // 读取路由规则(来自 route/app.php)
    $rules = include $this->getRoutePath() . 'app.php';

    // 创建路由对象
    $this->route = new Route($this);

    // 导入路由规则
    $this->route->import($rules);

    // 请求对象
    $request = $this->request;

    // 路由调度:解析 URL → 找到控制器和方法
    return $this->route->dispatch($request);
}
路由匹配流程:
根据请求方法(GET/POST)和路径(如 /user/123)匹配路由规则。
支持闭包路由、控制器路由、资源路由。
生成 Dispatch 对象(可能是 Module, Controller, Callback 类型)。
✅ 路由缓存:如果启用了路由缓存,会直接读取 runtime/route_cache.php,跳过解析。

6. $this->dispatch($dispatch):执行调度
protected function dispatch($dispatch)
{
    // 创建中间件栈
    $middleware = $this->middleware->import();

    // 推入全局中间件
    foreach ($middleware as $item) {
        $this->middleware->push($item);
    }

    // 执行中间件 + 最终调用控制器
    return $this->middleware->dispatch($dispatch);
}
7. 中间件执行:Middleware->dispatch()
文件:think/Middleware.php
public function dispatch($dispatch)
{
    $next = function ($dispatch) use (&$next) {
        // 这是“最终处理器”:调用控制器
        return $this->handler($dispatch);
    };

    // 从后往前封装中间件(洋葱模型)
    while ($stack = array_pop($this->queue)) {
        $next = function () use ($stack, $next) {
            return $stack->handle($this->request, $next);
        };
    }

    return $next($dispatch);
}
洋葱模型(Onion Model):
深色版本
Request → Middleware 3 → Middleware 2 → Middleware 1 → Controller
                             ↑                ↑              ↑
Response ← Middleware 3 ← Middleware 2 ← Middleware 1 ← Controller
✅ 中间件通过闭包嵌套实现“环绕执行”。

8. $this->handler($dispatch):调用控制器
protected function handler($dispatch)
{
    if ($dispatch instanceof ControllerDispatch) {
        [$controller, $action] = $this->parseControllerAndAction($dispatch);

        // 从容器创建控制器(自动注入依赖)
        $instance = $this->app->make($controller);

        // 调用控制器方法
        return call_user_func([$instance, $action], $this->request);
    }
}
控制器依赖注入示例:
class UserController
{
    public function __construct(private UserService $userService) {}

    public function index()
    {
        return $this->userService->getList(); // 自动注入
    }
}
✅ 容器自动解析构造函数依赖,实现 DI。

9. 控制器返回数据 → 生成响应
控制器可以返回:

字符串
数组(自动转 JSON)
Response 对象
视图(View)
// TP6 自动包装为 Response
return json(['name' => 'thinkphp']);
// 等价于
return Response::create(['name' => 'thinkphp'], 'json');
10. $app->response($data):包装响应
protected function response($data): Response
{
    if (!$data instanceof Response) {
        // 根据内容类型自动创建 Response
        $type = $this->request->getResponseFormat();
        $data = Response::create($data, $type);
    }

    return $data;
}
11. ->send():发送响应并结束

public function send()
{
    // 发送 HTTP 头
    $this->sendHeader();

    // 发送内容
    echo $this->getContent();

    // 触发响应结束事件
    $this->app->event->trigger('ResponseEnd');

    // 结束
    exit;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Discuz! X

GMT+8, 2025-12-6 12:38 , Processed in 0.088806 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表