thinkphp5.1原始碼閱讀與學習(框架初始化)

K_G發表於2021-02-20

1 框架初始化過程

在入口檔案(public/index.php)中,完成框架的基礎環境搭建後

呼叫容器Container獲取app應用物件,然後呼叫app的run()方法進行框架的整個執行過程。

在整個執行過程中,首先進行框架的初始化 包含app的initialize()和init()方法

所以框架的初始化在(/library/think/App.php)app的run()方法中完成

2 初始化

2-1 initialize()
2-2 init()
2-1 initialize()
$this->beginTime = microtime(true);
$this->beginMem = memory_get_usage();
$this->thinkPath = dirname(dirname(DIR)) . ‘/‘;
$this->rootPath = dirname(realpath($this->appPath)) . ‘/‘;
$this->runtimePath = $this->rootPath . ‘runtime/‘;
$this->routePath = $this->rootPath . ‘route/‘;
$this->configPath = $this->rootPath . ‘config/‘;
1 設定執行資訊。

框架開始執行時,開始執行記憶體 beginTime,beginMem
框架的各個主要目錄
thinkPath 框架目錄
rootPath 根目錄
runtimePath 執行時資料目錄
routePath 路由配置目錄
configPath 配置定義目錄

$this->env->set([
‘think_path’ => $this->thinkPath,
‘root_path’ => $this->rootPath,
‘app_path’ => $this->appPath,
‘config_path’ => $this->configPath,
‘route_path’ => $this->routePath,
‘runtime_path’ => $this->runtimePath,
‘extend_path’ => $this->rootPath . ‘extend/‘,
‘vendor_path’ => $this->rootPath . ‘vendor/‘,
]);
2 儲存目錄引數到env屬性中

think_path 框架目錄
root_path 根目錄
app_path 應用目錄
config_path 配置檔案目錄
route_path 路由配置目錄
runtime_path 執行時資料目錄
extend_path 自動載入目錄
vendor 擴充套件目錄

if (is_file($this->rootPath . ‘.env’)) {
$this->env->load($this->rootPath . ‘.env’);
}
3 讀取根目錄下的.env檔案 載入環境配置變數到env屬性

$this->namespace = $this->env->get(‘app_namespace’, $this->namespace);
$this->env->set(‘app_namespace’, $this->namespace);
Loader::addNamespace($this->namespace, $this->appPath);
4 讀取.env設定的app_namespace名稱空間名稱,如果沒有配置,則讀取app的namespace屬性。預設為app

然後設定env的app_namespace為應用名稱空間名稱app
呼叫Loader的addNamespace註冊名稱空間名稱app與應用目錄/app的對應關係

$this->configExt = $this->env->get(‘config_ext’, ‘.php’);
5 讀取配置檔案字尾 預設為.php

$this->init();
6 應用初始化。初始化過程init()見下面

$this->suffix = $this->config(‘app.class_suffix’);
7 獲取類名字尾是否開啟,預設不開啟。開啟是控制器和模型檔案的檔名需要加上對應字尾

$this->debug = $this->env->get(‘app_debug’, $this->config(‘app.app_debug’));
$this->env->set(‘app_debug’, $this->debug);

if (!$this->debug) {
ini_set(‘display_errors’, ‘Off’);
} elseif (PHP_SAPI != ‘cli’) {
//重新申請一塊比較大的buffer
if (ob_get_level() > 0) {
$output = ob_get_clean();
}
ob_start();
if (!empty($output)) {
echo $output;
}
}
8 應用除錯模式的開啟

if (!empty($this->config(‘app.root_namespace’))) {
Loader::addNamespace($this->config(‘app.root_namespace’));
}

Loader::addClassAlias($this->config->pull(‘alias’));
9 註冊名稱空間與目錄的對應 註冊檔名與別名的對應關係

date_default_timezone_set($this->config(‘app.default_timezone’));
$this->loadLangPack();
10 設定系統時區和載入語言包

$this->hook->listen(‘app_init’);
11 呼叫註冊的app_init回撥

2-2 init()
0 在initialize()中呼叫init()進行應用的初始化

init()傳入引數時,初始化對應的模組。引數為空時初始化整個應用。

這裡沒有傳入引數,進行整個應用的初始化

$module = $module ? $module . DIRECTORY_SEPARATOR : ‘’;
$path = $this->appPath . $module;
1 進行初始化的目錄 這裡是應用的根目錄/app/

if (is_file($path . ‘init.php’)) {
include $path . ‘init.php’;
} elseif (is_file($this->runtimePath . $module . ‘init.php’)) {
include $this->runtimePath . $module . ‘init.php’;
} else {
// 載入行為擴充套件檔案
if (is_file($path . ‘tags.php’)) {
$this->hook->import(include $path . ‘tags.php’);
}

// 載入公共檔案
if (is_file($path . 'common.php')) {
    include $path . 'common.php';
}

if ('' == $module) {
    // 載入系統助手函式
    include $this->thinkPath . 'helper.php';
}

// 註冊服務的容器物件例項
if (is_file($path . 'provider.php')) {
    $this->container->bind(include $path . 'provider.php');
}

// 自動讀取配置檔案
if (is_dir($path . 'config')) {
    $dir = $path . 'config';
} elseif (is_dir($this->configPath . $module)) {
    $dir = $this->configPath . $module;
}

$files = isset($dir) ? scandir($dir) : [];

foreach ($files as $file) {
    if ('.' . pathinfo($file, PATHINFO_EXTENSION) === $this->configExt) {
        $filename = $dir . DIRECTORY_SEPARATOR . $file;
        $this->config->load($filename, pathinfo($file, PATHINFO_FILENAME));
    }
}

}
2 讀取/app/init.php的初始化配置
/app/init.php不存在時,則讀取執行時目錄/runtime/init.php文

如果不存在init.php檔案,則讀取其他配置檔案

其他配置檔案包括 :

行為擴充套件 /app/tags.php.
公共內容檔案 /app/common.php
助手函式檔案 /app/helper.php
容器物件註冊檔案 /app/provider.php
讀取配置目錄下的配置檔案 /app/config/xx.php。註冊配置內容

$this->request->filter($this->config(‘app.default_filter’));
3 設定全域性請求過濾方法

3 請求排程與建立響應

在app的run()方法中框架初始化後,開始進行請求排程
排程分派,執行應用對應的業務邏輯,
根據業務邏輯的處理結果,建立相應的響應物件

請求排程與建立響應 見 下一節的 請求響應
應用業務邏輯 見 MVC核心

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章