[CodeIgniter4]講解-啟動流程

https://codeigniter.org.cn/forums/thread-31030-1-1.html

CodeIgniter 是一個小巧但功能強大的 PHP 框架,作為一個簡單而「優雅」的工具包,它可以為開發者們建立功能完善的 Web 應用程式。來自CodeIgniter中國的介紹 CodeIgniter 是一個輕量級、快速、靈活和安全的PHP全棧Web框架。CodeIgniter4 是一個完整的重寫,將品質和程式碼帶入一個更現代的版本,同時仍然保持著許多完整的東西來自CodeIgniter4 Github的介紹 CodeIgniter4 啟動流程分析 個人閱讀筆記,僅作參考,若有錯誤後續改正 簡要說明 入口文件index.php進行一些初始化動作 調用框架引導文件Systembootstrap.php預定義常量及載入相關類庫,然後對CodeIgniterCodeIgniter進行初始化並返回 調用CodeIgniterCodeIgniter->run()執行主流程並返迴響應結果 入口文件 – publicindex.php 檢測 PHP 版本 >= 7.2 定義前端入口路徑FCPATH 將當前路徑修改為工作目錄 載入並實例化項目路徑配置類 app/Config/Paths.php 載入框架引導文件 bootstrap.php,並實例化框架核心類 CodeIgniterCodeIgniter ,下文簡稱 CI 類,執行過程如下 執行 CI->run(),解析請求、路由,執行控制器並返迴響應結果 框架引導文件 – Systembootstrap.php 引導文件主要做了以下幾件事 預定義常量 載入相關類庫 引入包管理工具Composer 解析環境配置 .env 初始化框架核心類 CI 預定義常量路徑相關常量 項目路徑 – APPPATH 項目根路徑 – ROOTPATH 框架路徑 – SYSTEMPATH 可寫文件夾路徑 – WRITEPATH 測試用例路徑 – TESTPATH 項目常量 項目命名空間 – APP_NAMESPACE Composer Autoload 路徑 – COMPOSER_PATH 時間單位常量 – SECOND MINUTE HOUR DAY MONTH YEAR DECADE 退出狀態碼 – EXIT_* 載入類庫 載入框架公共函數庫 載入AUTOLOADER,並註冊spl_autoload_register 檢測Composer,存在則載入 載入並解析 env 配置,默認是 ROOTPATH.env 載入框架的URL輔助函數庫 初始化核心框架類CI 實例化框架核心類 CI 並初始化,初始化主要做了以下事情 根據配置設置默認時區,未配置則默認UTC 通過Services實例化CodeIgniterDebugExceptions         return static::getSharedInstance('exceptions', $config, $request, $response); 通過CodeIgniterDebugExceptions->initialize()註冊異常處理         //Set the Exception Handler        set_exception_handler([$this, 'exceptionHandler']);        // Set the Error Handler        set_error_handler([$this, 'errorHandler']);        // Set the handler for shutdown to catch Parse errors        // Do we need this in PHP7?        register_shutdown_function([$this, 'shutdownHandler']); 檢測並載入項目對應的環境啟動配置 Config/Boot/ENVIRONMENT(環境).php 根據CI_DEBUG標誌來載入調試類庫Kint 返回CI類 執行主流程 – CI->run() 開始基準測試 獲取CodeIgniterHTTPRequest對象 獲取CodeIgniterHTTPResponse對象 檢測安全訪問(Https) 檢測Request魔術方法($_POST['_method']) 執行pre_system事件觸發器 實例化ConfigCache,根據當前URI檢測快取,存在則直接輸出響應結果 調用CI->handleRequest()處理請求,詳細解析見下文         $this->handleRequest($routes, $cacheConfig, $returnResponse);處理請求 – CI->handleRequest() 解析當前請求路由並獲取過濾器$routeFilter 實例化過濾器CodeIgniterFiltersFilters 檢測$routeFilter過濾器,不為空則啟用before after 過濾器 獲取$uri,針對Web CLI兩種模式進行了處理 檢測SPARKED標誌,未定義則運行當前的before過濾器,並針對結果RedirectResponseResponseInterface 進行處理 啟動控制器CI->startController(),若當前控制器是閉包Closure則執行並返回執行結果,如果當前控制器為空、不存在或方法不存在則返回異常 如果當前控制器不是閉包且存在則創建控制器CI->createController(),實例並初始化控制器 初始化Request Response Logger 檢測Https 載入輔助函數庫 執行post_controller_constructor事件觸發器 運行控制器CI->runController() 檢測 Controller->_remap方法 存在則傳入Controller->method及請求參數調用_remap 不存在則直接調用Controller->method 返回相應輸出 聚合輸出gatherOutput,根據快取標誌對文本響應結果進行快取 檢測SPARKED標誌,未定義則傳入Response到after過濾器處理,獲取返回的Response 存儲當前URI資訊,然後移除$uri $_SESSION['_ci_previous_url'] = (string) $uri; 根據$returnResponse參數 false則執行發送響應報文CI->sendResponse() 執行post_system事件觸發器 返迴響應$this->response

  • 入口文件index.php進行一些初始化動作
  • 調用框架引導文件Systembootstrap.php預定義常量及載入相關類庫,然後對CodeIgniterCodeIgniter進行初始化並返回
  • 調用CodeIgniterCodeIgniter->run()執行主流程並返迴響應結果

入口文件 – publicindex.php

  • 檢測 PHP 版本 >= 7.2
  • 定義前端入口路徑FCPATH
  • 將當前路徑修改為工作目錄
  • 載入並實例化項目路徑配置類 app/Config/Paths.php
  • 載入框架引導文件 bootstrap.php,並實例化框架核心類 CodeIgniterCodeIgniter ,下文簡稱 CI 類,執行過程如下
  • 執行 CI->run(),解析請求、路由,執行控制器並返迴響應結果

框架引導文件 – Systembootstrap.php 引導文件主要做了以下幾件事

  • 預定義常量
  • 載入相關類庫
  • 引入包管理工具Composer
  • 解析環境配置 .env
  • 初始化框架核心類 CI

預定義常量路徑相關常量

  • 項目路徑 – APPPATH
  • 項目根路徑 – ROOTPATH
  • 框架路徑 – SYSTEMPATH
  • 可寫文件夾路徑 – WRITEPATH
  • 測試用例路徑 – TESTPATH

項目常量

  • 項目命名空間 – APP_NAMESPACE
  • Composer Autoload 路徑 – COMPOSER_PATH
  • 時間單位常量 – SECOND MINUTE HOUR DAY MONTH YEAR DECADE
  • 退出狀態碼 – EXIT_*

載入類庫

  • 載入框架公共函數庫
  • 載入AUTOLOADER,並註冊spl_autoload_register
  • 檢測Composer,存在則載入
  • 載入並解析 env 配置,默認是 ROOTPATH.env
  • 載入框架的URL輔助函數庫

初始化核心框架類CI

  • 實例化框架核心類 CI 並初始化,初始化主要做了以下事情
    • 根據配置設置默認時區,未配置則默認UTC
    • 通過Services實例化CodeIgniterDebugExceptions

return static::getSharedInstance('exceptions', $config, $request, $response);

  • 通過CodeIgniterDebugExceptions->initialize()註冊異常處理

//Set the Exception Handler        set_exception_handler([$this, 'exceptionHandler']);        // Set the Error Handler        set_error_handler([$this, 'errorHandler']);        // Set the handler for shutdown to catch Parse errors // Do we need this in PHP7?        register_shutdown_function([$this, 'shutdownHandler']);

  • 檢測並載入項目對應的環境啟動配置 Config/Boot/ENVIRONMENT(環境).php
  • 根據CI_DEBUG標誌來載入調試類庫Kint
  • 返回CI類

執行主流程 – CI->run()

  • 開始基準測試
  • 獲取CodeIgniterHTTPRequest對象
  • 獲取CodeIgniterHTTPResponse對象
  • 檢測安全訪問(Https)
  • 檢測Request魔術方法($_POST['_method'])
  • 執行pre_system事件觸發器
  • 實例化ConfigCache,根據當前URI檢測快取,存在則直接輸出響應結果
  • 調用CI->handleRequest()處理請求,詳細解析見下文

$this->handleRequest($routes, $cacheConfig, $returnResponse);處理請求 – CI->handleRequest()

  • 解析當前請求路由並獲取過濾器$routeFilter
  • 實例化過濾器CodeIgniterFiltersFilters
  • 檢測$routeFilter過濾器,不為空則啟用before after 過濾器
  • 獲取$uri,針對Web CLI兩種模式進行了處理
  • 檢測SPARKED標誌,未定義則運行當前的before過濾器,並針對結果RedirectResponseResponseInterface 進行處理
  • 啟動控制器CI->startController(),若當前控制器是閉包Closure則執行並返回執行結果,如果當前控制器為空、不存在或方法不存在則返回異常
  • 如果當前控制器不是閉包且存在則創建控制器CI->createController(),實例並初始化控制器
    • 初始化Request Response Logger
    • 檢測Https
    • 載入輔助函數庫
  • 執行post_controller_constructor事件觸發器
  • 運行控制器CI->runController()
    • 檢測 Controller->_remap方法
      • 存在則傳入Controller->method及請求參數調用_remap
      • 不存在則直接調用Controller->method
    • 返回相應輸出
  • 聚合輸出gatherOutput,根據快取標誌對文本響應結果進行快取
  • 檢測SPARKED標誌,未定義則傳入Response到after過濾器處理,獲取返回的Response
  • 存儲當前URI資訊,然後移除$uri

$_SESSION['_ci_previous_url'] = (string) $uri;

  • 根據$returnResponse參數
    • false則執行發送響應報文CI->sendResponse()
  • 執行post_system事件觸發器
  • 返迴響應$this->response