tp6源码分析之执行HTTP应用类的run方法启动一个HTTP应用

7.执行HTTP应用类的run方法启动一个HTTP应用

tp6\public\index.php

$response = $http->run();

8.获取当前请求对象实例(默认为 app\Request 继承think\Request)保存到容器

tp6\vendor\topthink\framework\src\think\Http->run

$request = $request ?? $this->app->make('request', [], true);
$this->app->instance('request', $request);

9.执行think\App类的初始化方法initialize

//tp6\vendor\topthink\framework\src\think\Http->run
$this->initialize();
//tp6\vendor\topthink\framework\src\think\Http->initialize
$this->app->initialize();

10.加载环境变量文件.env和全局初始化文件

//tp6\vendor\topthink\framework\src\think\App->initialize
$this->loadEnv($this->envName); //$this->envName 是个""

        // 加载环境变量
$envFile = $envName ? $this->rootPath . '.env.' . $envName : $this->rootPath . '.env';
        if (is_file($envFile)) {
            $this->env->load($envFile);
        }

//tp6\vendor\topthink\framework\src\think\Env->load
  //分析配置文件
  $env = parse_ini_file($file, true, INI_SCANNER_RAW) ?: [];
  $this->set($env);
//tp6\vendor\topthink\framework\src\think\Env->set
        if (is_array($env)) {
            //更改数组中所有键的大小写
            $env = array_change_key_case($env, CASE_UPPER);
            foreach ($env as $key => $val) {
                if (is_array($val)) {
                    foreach ($val as $k => $v) { 
                                                //使字符串大写
                        $this->data[$key . '_' . strtoupper($k)] = $v;
                    }
                } else {
                    $this->data[$key] = $val;
                }
            }
        } else {
            $name = strtoupper(str_replace('.', '_', $env));
            $this->data[$name] = $value;
        }

11.加载全局公共文件、系统助手函数、全局配置文件、全局事件定义和全局服务定义

//tp6\vendor\topthink\framework\src\think\App->initialize
$this->load();
//tp6\vendor\topthink\framework\src\think\App->load
        $appPath = $this->getAppPath();
        if (is_file($appPath . 'common.php')) {
            //加载全局公共文件
            include_once $appPath . 'common.php';
        }
        //系统助手函数
        include_once $this->thinkPath . 'helper.php';
        $configPath = $this->getConfigPath();
        $files = [];
        //如果文件名存在并且是目录,则为true,否则为false。
        if (is_dir($configPath)) {
            // 查找与模式匹配的路径名
            $files = glob($configPath . '*' . $this->configExt);
        }
        foreach ($files as $file) {
            //全局配置文件
            $this->config->load($file, pathinfo($file, PATHINFO_FILENAME));
        }
        if (is_file($appPath . 'event.php')) {
            //全局事件定义
            $this->loadEvent(include $appPath . 'event.php');
        }
        if (is_file($appPath . 'service.php')) {
            $services = include $appPath . 'service.php';
            foreach ($services as $service) {
                //全局服务定义
                $this->register($service);
            }
        }

12.判断应用模式(调试或者部署模式)

//tp6\vendor\topthink\framework\src\think\App->initialize
$this->debugModeInit();
//tp6\vendor\topthink\framework\src\think\App->debugModeInit
        // 应用调试模式
        if (!$this->appDebug) {
            $this->appDebug = $this->env->get('app_debug') ? true : false;
            //设置配置选项的值
            ini_set('display_errors', 'Off');
        }
        //是否运行在命令行下
        //返回输出缓冲机制的嵌套级别
        if (!$this->runningInConsole()) {
            //重新申请一块比较大的buffer
            if (ob_get_level() > 0) {
                //获取当前缓冲区内容并删除当前输出缓冲区
                $output = ob_get_clean();
            }
            //打开输出缓冲
            ob_start();
            if (!empty($output)) {
                echo $output;
            }
        }

 13.监听AppInit事件

//tp6\vendor\topthink\framework\src\think\App->initialize
$this->event->trigger(AppInit::class);
/**
 * AppInit事件类
 */
class AppInit
{}

14.注册异常处理  15.服务注册  16.启动注册的服务

//tp6\vendor\topthink\framework\src\think\App->initialize
        foreach ($this->initializers as $initializer) {
            //注册异常处理 服务注册 启动注册的服务
            $this->make($initializer)->init($this);
        }

    protected $initializers = [
        Error::class,
        RegisterService::class,
        BootService::class,
    ];

17. 加载全局中间件定义

//tp6\vendor\topthink\framework\src\think\Http->runWithRequest
$this->loadMiddleware();
    protected function loadMiddleware(): void
    {
        if (is_file($this->app->getBasePath() . 'middleware.php')) {
            $this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php');
        }
    }

18.监听HttpRun事件

//tp6\vendor\topthink\framework\src\think\Http->runWithRequest
$this->app->event->trigger(HttpRun::class);
/**
 * HttpRun事件类
 */
class HttpRun
{}

19.执行全局中间件

//tp6\vendor\topthink\framework\src\think\Http->runWithRequest
//会返回一个 think\response\Html 对象
        return $this->app->middleware->pipeline()
            ->send($request)
            ->then(function ($request) {
                return $this->dispatchToRoute($request);
            });
//tp6\vendor\topthink\framework\src\think\Middleware->pipeline
    /**
     * 调度管道
     * @access public
     * @param string $type 中间件类型
     * @return Pipeline
     */
    public function pipeline(string $type = 'global')
    {
        return (new Pipeline())
            ->through(array_map(function ($middleware) {
                return function ($request, $next) use ($middleware) {
                    [$call, $params] = $middleware;
                    if (is_array($call) && is_string($call[0])) {
                        $call = [$this->app->make($call[0]), $call[1]];
                    }
                   //调用第一个参数给出的回调
                    $response = call_user_func($call, $request, $next, ...$params);
                    if (!$response instanceof Response) {
                        throw new LogicException('The middleware must return Response instance');
                    }
                    return $response;
                };
                //中间件排序
            }, $this->sortMiddleware($this->queue[$type] ?? [])))
                //设置异常处理器
            ->whenException([$this, 'handleException']);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值