小編給大家分享一下ThinkPHP6應(yīng)用初始化的實(shí)現(xiàn)方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
公司專注于為企業(yè)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、電子商務(wù)商城網(wǎng)站建設(shè),小程序開發(fā),軟件按需網(wǎng)站策劃等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。憑借多年豐富的經(jīng)驗(yàn),我們會(huì)仔細(xì)了解各客戶的需求而做出多方面的分析、設(shè)計(jì)、整合,為客戶設(shè)計(jì)出具風(fēng)格及創(chuàng)意性的商業(yè)解決方案,成都創(chuàng)新互聯(lián)公司更提供一系列網(wǎng)站制作和網(wǎng)站推廣的服務(wù)。ThinkPHP6 源碼分析之應(yīng)用初始化
App Construct
先來(lái)看看在 __construct 中做了什么,基本任何框架都會(huì)在這里做一些基本的操作,也就是從這里開始延伸出去。
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 來(lái)看,是支持自定義根目錄路徑的。
● 設(shè)置了 thinkPath, rootPath, appPath, runtimePath
● 綁定了默認(rèn)的服務(wù)提供者,一共提供了兩個(gè),app\Reques 和 app\ExceptionHandle,實(shí)際上你使用的 Request 就是它。具體到 appPath 查看
● 設(shè)置當(dāng)前容器實(shí)例 APP
● 將 App($this) 實(shí)例 綁定到容器中,分別是 app 和 think\Container
這里需要注意的是 App 類是繼承 Container 的,所以就是將自身實(shí)例綁定到容器中。
在這里似乎整個(gè)應(yīng)用就已經(jīng)初始化結(jié)束了?這里我需要把一部分 Request run 的內(nèi)容放在這里說(shuō),因?yàn)槟抢锊攀强蚣苤饕某跏蓟ぷ?,我并不認(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)語(yǔ)言包 $langSet = $this->lang->defaultLangSet(); $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php'); // 加載應(yīng)用默認(rèn)語(yǔ)言包 $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 事件
● 注冊(cè)應(yīng)用目錄下的 service.php 服務(wù)
● 加載語(yǔ)言包
● 監(jiān)聽 AppInit 事件,利用該事件可以做一些請(qǐng)求前的工作
● 設(shè)置時(shí)區(qū)
● 注入所有服務(wù)并且啟動(dòng)服務(wù)
服務(wù)注冊(cè)
初始化過(guò)程中,進(jìn)行服務(wù)注冊(cè),那么服務(wù)注冊(cè)做了哪些事情呢?該如何使用的服務(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ù)是否注冊(cè)過(guò),如果需要強(qiáng)制重新注冊(cè)
● 實(shí)例化服務(wù)
● 如果實(shí)現(xiàn)了 register 方法,則需要執(zhí)行 register 方法
● 如果設(shè)置了 bind 屬性,則需要將 service 實(shí)例綁定到容器
● 最后合并到整個(gè) service 數(shù)組中,等待 boot
服務(wù)啟動(dòng)
目前在初始化的時(shí)候只有下面三個(gè)服務(wù),在 $this->initializers 數(shù)組中
foreach ($this->initializers as $initializer) { $this->make($initializer)->init($this); }
這三個(gè)服務(wù)分別是:
think\initializer\BootService think\initializer\Error think\initializer\RegisterService
● Error 服務(wù)是用來(lái)處理框架異常和錯(cuò)誤的
● RegisterService 從字面的意思就是注冊(cè)服務(wù)的
● BootService 就是啟用服務(wù)的
Error 處理在之后再說(shuō),這里說(shuō)一下 RegisterService 和 BootService。
當(dāng)從 Container 中 make 出 RegisterService 的時(shí)候
這里有個(gè)隱藏的靜態(tài)方法 make,每次如果首次從 Container 中 make 出來(lái)的實(shí)例對(duì)象都會(huì)執(zhí)行 make 方法,當(dāng)然首先必須你實(shí)現(xiàn)了該方法。
隨后會(huì)執(zhí)行 Init 方法。當(dāng)你進(jìn)入到 RegisterService 的時(shí)候,你會(huì)看到該方法。方法內(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); } } }
該方法就很奇怪了,和我想象的有點(diǎn)不一樣。服務(wù)是直接從 runtime 目錄下面獲取的,而非在 config 目錄下的 service.php 中。為什么會(huì)這樣呢?由于 composer 的發(fā)展,TP 框架也可以提供包的自動(dòng)發(fā)現(xiàn)的功能,這也證明了開發(fā)組在不斷向社區(qū)靠攏。下面來(lái)看一下是如何實(shí)現(xiàn)的。
因?yàn)檫@都是得益于 composer 的,所以來(lái)看一下 rootPath 下的 composer.json,到最下面,你會(huì)發(fā)現(xiàn)下面的配置
"scripts": { "post-autoload-dump": [ "@php think service:discover", "@php think vendor:publish" ] }
從配置來(lái)看,框架一共提供了兩個(gè)指令,service:discover 和 vendor:publish。具體實(shí)現(xiàn)這里就不說(shuō)了,你只需要知道包的發(fā)現(xiàn)是由 service:discover 實(shí)現(xiàn)的。
還有就是這里默認(rèn)注入了三個(gè)服務(wù)。
PaginatorService::class, ValidateService::class, ModelService::class,
最后再來(lái)看看 BootService,這個(gè)就很簡(jiǎn)單了。從命名來(lái)講就不難看出,下面就是代碼,正常的啟動(dòng)服務(wù),但是這里要說(shuō)明的是,服務(wù)類中必須實(shí)現(xiàn)了 boot 方法才會(huì)啟動(dòng)。
public function init(App $app) { $app->boot(); }
以上是“ThinkPHP6應(yīng)用初始化的實(shí)現(xiàn)方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站標(biāo)題:ThinkPHP6應(yīng)用初始化的實(shí)現(xiàn)方法-創(chuàng)新互聯(lián)
標(biāo)題來(lái)源:http://www.rwnh.cn/article32/ijppc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、云服務(wù)器、品牌網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、服務(wù)器托管、全網(wǎng)營(yíng)銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容