真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ThinkPHP6應(yīng)用初始化的實現(xiàn)方法

小編給大家分享一下ThinkPHP6應(yīng)用初始化的實現(xiàn)方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

成都創(chuàng)新互聯(lián)公司2013年至今,先為清河等服務(wù)建站,清河等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為清河企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

ThinkPHP6 源碼分析之應(yīng)用初始化

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);
}

● 從魔術(shù)的方法的參數(shù) rootPath 來看,是支持自定義根目錄路徑的。

● 設(shè)置了 thinkPath, rootPath, appPath, runtimePath

● 綁定了默認(rèn)的服務(wù)提供者,一共提供了兩個,app\Reques 和 app\ExceptionHandle,實際上你使用的 Request 就是它。具體到 appPath 查看

● 設(shè)置當(dāng)前容器實例 APP

● 將 App($this) 實例 綁定到容器中,分別是 app 和 think\Container

這里需要注意的是 App 類是繼承 Container 的,所以就是將自身實例綁定到容器中。

在這里似乎整個應(yīng)用就已經(jīng)初始化結(jié)束了?這里我需要把一部分 Request run 的內(nèi)容放在這里說,因為那里才是框架主要的初始化工作,我并不認(rèn)為將這一部分初始化工作放在 Request run 中是合理的。

主要的初始化

public function initialize()
{
    $this->initialized = true;
    $this->beginTime = microtime(true);
    $this->beginMem  = memory_get_usage();
    // 加載環(huán)境變量
    if (is_file($this->rootPath . '.env')) {
        $this->env->load($this->rootPath . '.env');
    }
    $this->configExt = $this->env->get('config_ext', '.php');
    $this->debugModeInit();
    // 加載全局初始化文件
    $this->load();
    // 加載框架默認(rèn)語言包
    $langSet = $this->lang->defaultLangSet();
    $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
    // 加載應(yīng)用默認(rèn)語言包
    $this->loadLangPack($langSet);
    // 監(jiān)聽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 環(huán)境變量文件

● 加載配置文件以及應(yīng)用內(nèi)的文件

● 加載應(yīng)用內(nèi)的 common.php

● 加載助手函數(shù) 在 thinkPath 目錄下的 helper.php

● 加載配置文件

● 加載應(yīng)用目錄下的 event.php 事件

● 注冊應(yīng)用目錄下的 service.php 服務(wù)

● 加載語言包

● 監(jiān)聽 AppInit 事件,利用該事件可以做一些請求前的工作

● 設(shè)置時區(qū)

● 注入所有服務(wù)并且啟動服務(wù)

服務(wù)注冊

初始化過程中,進(jìn)行服務(wù)注冊,那么服務(wù)注冊做了哪些事情呢?該如何使用的服務(wù)呢?

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;
}

● 服務(wù)是否注冊過,如果需要強制重新注冊

● 實例化服務(wù)

● 如果實現(xiàn)了 register 方法,則需要執(zhí)行 register 方法

● 如果設(shè)置了 bind 屬性,則需要將 service 實例綁定到容器

● 最后合并到整個 service 數(shù)組中,等待 boot

服務(wù)啟動

目前在初始化的時候只有下面三個服務(wù),在 $this->initializers 數(shù)組中

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

這三個服務(wù)分別是:

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

● Error 服務(wù)是用來處理框架異常和錯誤的

● RegisterService 從字面的意思就是注冊服務(wù)的

● BootService 就是啟用服務(wù)的

Error 處理在之后再說,這里說一下 RegisterService 和 BootService。

當(dāng)從 Container 中 make 出 RegisterService 的時候

這里有個隱藏的靜態(tài)方法 make,每次如果首次從 Container 中 make 出來的實例對象都會執(zhí)行 make 方法,當(dāng)然首先必須你實現(xiàn)了該方法。

隨后會執(zhí)行 Init 方法。當(dāng)你進(jìn)入到 RegisterService 的時候,你會看到該方法。方法內(nèi)容如下:

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);
        }
    }
}

該方法就很奇怪了,和我想象的有點不一樣。服務(wù)是直接從 runtime 目錄下面獲取的,而非在 config 目錄下的 service.php 中。為什么會這樣呢?由于 composer 的發(fā)展,TP 框架也可以提供包的自動發(fā)現(xiàn)的功能,這也證明了開發(fā)組在不斷向社區(qū)靠攏。下面來看一下是如何實現(xiàn)的。

因為這都是得益于 composer 的,所以來看一下 rootPath 下的 composer.json,到最下面,你會發(fā)現(xiàn)下面的配置

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

從配置來看,框架一共提供了兩個指令,service:discover 和 vendor:publish。具體實現(xiàn)這里就不說了,你只需要知道包的發(fā)現(xiàn)是由 service:discover 實現(xiàn)的。

還有就是這里默認(rèn)注入了三個服務(wù)。

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

最后再來看看 BootService,這個就很簡單了。從命名來講就不難看出,下面就是代碼,正常的啟動服務(wù),但是這里要說明的是,服務(wù)類中必須實現(xiàn)了 boot 方法才會啟動。

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

以上是“ThinkPHP6應(yīng)用初始化的實現(xiàn)方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


網(wǎng)站欄目:ThinkPHP6應(yīng)用初始化的實現(xiàn)方法
文章轉(zhuǎn)載:http://weahome.cn/article/ipphjc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部