運行機制及流程
1.入口文件index.php
獨立模式
define('APP_PATH', __DIR__ . '/../application/');define('APP_DEBUG', true);require __DIR__ . '/../thinkphp/start.php';
composer模式
define('APP_PATH', __DIR__ . '/../application/');define('APP_DEBUG', true);if (is_file(__DIR__ . '/../vendor/autoload.php')) { require_once __DIR__ . '/../vendor/autoload.php';} else { require __DIR__ . '/../thinkphp/start.php';}
2.框架引導文件start.php
namespace think;// ThinkPHP 引導文件// 加載基礎文件require __DIR__ . '/base.php';// 執行應用App::run()->send();
3.html' target='_blank'>全局變量文件base.php
define('THINK_VERSION', '5.0.2'); //TP版本號define('THINK_START_TIME', microtime(true));//啟動時間define('THINK_START_MEM', memory_get_usage());//獲取分配給 PHP 的內存量define('EXT', '.php'); //文件后綴define('DS', DIRECTORY_SEPARATOR);//系統分隔符defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS);//項目根目錄define('LIB_PATH', THINK_PATH . 'library' . DS);//類庫目錄define('CORE_PATH', LIB_PATH . 'think' . DS);//核心文件目錄define('TRAIT_PATH', LIB_PATH . 'traits' . DS);//復用機制文件目錄defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS);//應用根目錄defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS);//根目錄defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);//擴展目錄defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS);//第三方庫和插件放置defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);//運行緩存目錄defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);//日志文件目錄defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);//緩存文件目錄defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);//臨時目錄defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目錄defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后綴defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 環境變量的配置前綴// 環境常量define('IS_CLI', PHP_SAPI == 'cli' ? true : false);define('IS_WIN', strpos(PHP_OS, 'WIN') !== false);// 載入Loader類require CORE_PATH . 'Loader.php';// 加載環境變量配置文件if (is_file(ROOT_PATH . '.env')) { $env = parse_ini_file(ROOT_PATH . '.env', true); foreach ($env as $key => $val) { $name = ENV_PREFIX . strtoupper($key); if (is_array($val)) { foreach ($val as $k => $v) { $item = $name . '_' . strtoupper($k); putenv("$item=$v"); } } else { putenv("$name=$val"); } }}// 注冊自動加載/think/Loader::register();// 注冊錯誤和異常處理機制/think/Error::register();// 加載慣例配置文件/think/Config::set(include THINK_PATH . 'convention' . EXT);
4.自動加載器文件Loader.php
Loader.php是框架的類的自動加載實現文件??梢允褂胊utoload()自動擋加載類,import()手動加載指定目錄的類。
protected static $map = []; 系統的類名映射緩存數組,在下面的addMap()使用
protected static $load = []; 系統的加載列表緩存數組,在下面的autoload()使用
protected static $namespace = []; 系統的命名空間緩存數組,在下面的addNamespace()使用
private static $prefixLengthsPsr4 = [];private static $prefixDirsPsr4 = [];
系統的PSR-4緩存數組,在下面的registerComposerLoader()使用
private static $prefixesPsr0 = []; 系統的PSR-0緩存數組,在下面的registerComposerLoader()使用。
上面四個靜態變量用作加載器的緩存數組,保證加載效率。
1 autoload($class)
根據類名自動加載。
public static function autoload($class){}
使用類庫映射加載對應的類。
if (isset(self::$map[$class])) { if (is_file(self::$map[$class])) { APP_DEBUG && self::$load[] = self::$map[$class]; include self::$map[$class]; }}
使用composer加載類
elseif ($file = self::findFileInComposer($class)) { APP_DEBUG && self::$load[] = $file; include $file;}
根據命名空間自動加載類
else { if (!strpos($class, '//')) { return; } list($name, $class) = explode('//', $class, 2); if (isset(self::$namespace[$name])) { $path = self::$namespace[$name]; } elseif (is_dir(EXTEND_PATH . $name)) { $path = EXTEND_PATH . $name . DS; } else { return; } $filename = $path . str_replace('//', DS, $class) . EXT; if (is_file($filename)) { if (APP_DEBUG && IS_WIN && false === strpos(realpath($filename), $class . EXT)) { return; } APP_DEBUG && self::$load[] = $filename; include $filename; } else { Log::record('autoloader error : ' . $filename, 'notice'); }}
2 addMap($class,$map='')
注冊類名映射
public static function addMap($class, $map = ''){} 數組合并到$map,字符串關聯到$class.
if (is_array($class)) { self::$map = array_merge(self::$map, $class);} else { self::$map[$class] = $map;}
3 addNamespace($namespace,$path)
注冊命名空間和路徑的關聯
public static function addNamespace($namespace, $path = ''){} 數組合并到$namespace,字符串關聯到path.
if (is_array($namespace)) { self::$namespace = array_merge(self::$namespace, $namespace);} else { self::$namespace[$namespace] = $path;}
4 register($autoload='')
注冊自動加載機制
public static function register($autoload = ''){} think/Loader::autoload()系統自動加載
self::registerComposerLoader() composer自動加載
spl_autoload_register($autoload ? $autoload : 'think//Loader::autoload');self::registerComposerLoader();
5 composer自動加載的注冊
private static function registerComposerLoader(){} 關于composer自動加載機制見 基礎原理的php的composer自動加載
6 composer自動加載的兩個私有方法
private static function composerRequire($fileIdentifier, $file){}private static function findFileInComposer($class, $ext = '.php'){}
7 import($class,$baseUrl='',$ext=EXT)
手動加載$baseUrl下的$class命名的$ext后綴文件
public static function import($class, $baseUrl = '', $ext = EXT){} 首先分析$baseUrl,
然后查找$baserUrl.$class.$ext 文件名,然后加載對應文件
以上就是PHP框架設計之ThinkPHP5源碼解析一的內容,更多相關內容請關注PHP (www.49028c.com)!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答