0

0

ThinkPHP6源码分析之应用初始化

藏色散人

藏色散人

发布时间:2019-08-01 14:21:58

|

3854人浏览过

|

来源于learnku

转载

thinkphp6 源码分析之应用初始化

App Construct

先来看看在 __construct 中做了什么,基本任何框架都会在这里做一些基本的操作,也就是从这里开始延伸出去。

public function __construct(string $rootPath = '')
{
    $this->thinkPath   = dirname(__DIR__) . DIRECTORY_SEPARATOR;
    $this->rootPath    = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
    $this->appPath     = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
    $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
    if (is_file($this->appPath . 'provider.php')) {
        $this->bind(include $this->appPath . 'provider.php');
    }
    static::setInstance($this);
    $this->instance('app', $this);
    $this->instance('think\Container', $this);
}

● 从魔术的方法的参数 rootPath 来看,是支持自定义根目录路径的。

● 设置了 thinkPath, rootPath, appPath, runtimePath

立即学习PHP免费学习笔记(深入)”;

● 绑定了默认的服务提供者,一共提供了两个,app\Reques 和 app\ExceptionHandle,实际上你使用的 Request 就是它。具体到 appPath 查看

● 设置当前容器实例 APP

● 将 App($this) 实例 绑定到容器中,分别是 app 和 think\Container

这里需要注意的是 App 类是继承 Container 的,所以就是将自身实例绑定到容器中。

在这里似乎整个应用就已经初始化结束了?这里我需要把一部分 Request run 的内容放在这里说,因为那里才是框架主要的初始化工作,我并不认为将这一部分初始化工作放在 Request run 中是合理的。

主要的初始化

public function initialize()
{
    $this->initialized = true;
    $this->beginTime = microtime(true);
    $this->beginMem  = memory_get_usage();
    // 加载环境变量
    if (is_file($this->rootPath . '.env')) {
        $this->env->load($this->rootPath . '.env');
    }
    $this->configExt = $this->env->get('config_ext', '.php');
    $this->debugModeInit();
    // 加载全局初始化文件
    $this->load();
    // 加载框架默认语言包
    $langSet = $this->lang->defaultLangSet();
    $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
    // 加载应用默认语言包
    $this->loadLangPack($langSet);
    // 监听AppInit
    $this->event->trigger('AppInit');
    date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai'));
    // 初始化
    foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
    }
    return $this;
}

● 加载 .env 环境变量文件

● 加载配置文件以及应用内的文件

    ● 加载应用内的 common.php

    ● 加载助手函数 在 thinkPath 目录下的 helper.php

● 加载配置文件

● 加载应用目录下的 event.php 事件

● 注册应用目录下的 service.php 服务

● 加载语言包

● 监听 AppInit 事件,利用该事件可以做一些请求前的工作

● 设置时区

● 注入所有服务并且启动服务

服务注册

初始化过程中,进行服务注册,那么服务注册做了哪些事情呢?该如何使用的服务呢?

MusicLM
MusicLM

谷歌平台的AI作曲工具,用文字生成音乐

下载
public function register($service, bool $force = false)
{
    $registered = $this->getService($service);
    if ($registered && !$force) {
        return $registered;
    }
    if (is_string($service)) {
        $service = new $service($this);
    }
    if (method_exists($service, 'register')) {
        $service->register();
    }
    if (property_exists($service, 'bind')) {
        $this->bind($service->bind);
    }
    $this->services[] = $service;
}

● 服务是否注册过,如果需要强制重新注册

● 实例化服务

● 如果实现了 register 方法,则需要执行 register 方法

● 如果设置了 bind 属性,则需要将 service 实例绑定到容器

● 最后合并到整个 service 数组中,等待 boot

服务启动

目前在初始化的时候只有下面三个服务,在 $this->initializers 数组中

foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
}

这三个服务分别是:

think\initializer\BootService
think\initializer\Error
think\initializer\RegisterService

● Error 服务是用来处理框架异常和错误的

● RegisterService 从字面的意思就是注册服务的

● BootService 就是启用服务的

Error 处理在之后再说,这里说一下 RegisterService 和 BootService。

当从 Container 中 make 出 RegisterService 的时候

这里有个隐藏的静态方法 make,每次如果首次从 Container 中 make 出来的实例对象都会执行 make 方法,当然首先必须你实现了该方法。

随后会执行 Init 方法。当你进入到 RegisterService 的时候,你会看到该方法。方法内容如下:

public function init(App $app)
{
    $file = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'services.php';
    $services = $this->services;
    if (is_file($file)) {
        $services = array_merge($services, include $file);
    }
    foreach ($services as $service) {
        if (class_exists($service)) {
            $app->register($service);
        }
    }
}

该方法就很奇怪了,和我想象的有点不一样。服务是直接从 runtime 目录下面获取的,而非在 config 目录下的 service.php 中。为什么会这样呢?由于 composer 的发展,TP 框架也可以提供包的自动发现的功能,这也证明了开发组在不断向社区靠拢。下面来看一下是如何实现的。

因为这都是得益于 composer 的,所以来看一下 rootPath 下的 composer.json,到最下面,你会发现下面的配置

"scripts": {
    "post-autoload-dump": [
        "@php think service:discover",
        "@php think vendor:publish"
    ]
}

从配置来看,框架一共提供了两个指令,service:discover 和 vendor:publish。具体实现这里就不说了,你只需要知道包的发现是由 service:discover 实现的。

还有就是这里默认注入了三个服务。

PaginatorService::class,
ValidateService::class,
ModelService::class,

最后再来看看 BootService,这个就很简单了。从命名来讲就不难看出,下面就是代码,正常的启动服务,但是这里要说明的是,服务类中必须实现了 boot 方法才会启动。

public function init(App $app)
{
    $app->boot();
}

以上就是整个应用的初始化,具体细节在之后讨论。

本文来自ThinkPHP框架技术文章栏目:http://www.php.cn/phpkj/thinkphp/

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

37

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

37

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

9

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ThinkPHP6.x 微实战--十天技能课堂
ThinkPHP6.x 微实战--十天技能课堂

共26课时 | 1.6万人学习

ThinkPHP6.x API接口--十天技能课堂
ThinkPHP6.x API接口--十天技能课堂

共14课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号