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
● 綁定了預設的服務提供者,總共提供了兩個,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 事件,利用該事件可以做一些請求前的工作
● 設定時區
● 注入所有服務並且啟動服務
#服務註冊
初始化過程中,進行服務註冊,那麼服務註冊做了哪些事情?該如何使用的服務呢?
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/
#以上是ThinkPHP6源碼分析之應用初始化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文討論了ThinkPHP的內置測試框架,突出了其關鍵功能(例如單元和集成測試),以及它如何通過早期的錯誤檢測和改進的代碼質量來增強應用程序可靠性。

本文討論了在無服務器體系結構中使用ThinkPHP的關鍵注意事項,專注於性能優化,無狀態設計和安全性。它突出了諸如成本效率和可擴展性之類的收益,但也應對挑戰

本文討論了在ThinkPHP微服務中實施服務發現和負載平衡,重點是設置,最佳實踐,集成方法和推薦工具。[159個字符]

ThinkPHP的IOC容器提供了高級功能,例如懶惰加載,上下文綁定和方法注入PHP App中有效依賴性管理的方法。Character計數:159

ThinkPHP具有輕巧的設計,MVC架構和可擴展性。它通過各種功能提高可擴展性,加快開發並提高安全性。

本文概述了使用ThinkPhp和RabbitMQ構建分佈式任務隊列系統,重點是安裝,配置,任務管理和可擴展性。關鍵問題包括確保高可用性,避免常見的陷阱,例如不當


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。