在覈心類文件Think.class.php裏,Think定義了autoload方法,並用spl_autoload_register註冊爲自動加載的方法。下面來解說下該方法的原理。
ThinkPHP的自動加載分三種情況:
1.map映射
Think類裏定義了$_map屬性,用來保存用戶添加的類映射信息
方法addMap和getMap分別用於添加和獲取映射信息。如果$_map裏存在$class的映射,則直接引入class,
// 檢查是否存在映射 if(isset(self::$_map[$class])) { include self::$_map[$class]; }
2.命名空間下的自動加載
首先判斷$class是否含有\\,用以區分命名空間自動加載和非命名空間加載。其結果無非獲取一:類的basename,二:類的dirname。然後拼接類的路徑
這裏有系統的命名空間和用戶自定義的命名空間,系統命名空間會自動定位,dirname爲LIB_PATH
$name = strstr($class, '\\', true); if(in_array($name,array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$name)){ // Library目錄下面的命名空間自動定位 $path = LIB_PATH; }
自定義命名空間以模塊爲命名空間,dirname爲模塊所在的上級目錄
// 檢測自定義命名空間 否則就以模塊爲命名空間 $namespace = C('AUTOLOAD_NAMESPACE'); $path = isset($namespace[$name])? dirname($namespace[$name]).'/' : APP_PATH;
最後拼接類的路徑,引入類文件
$filename = $path . str_replace('\\', '/', $class) . EXT; if(is_file($filename)) { // Win環境下面嚴格區分大小寫 if (IS_WIN && false === strpos(str_replace('/', '\\', realpath($filename)), $class . EXT)){ return ; } include $filename;
3.不是用命名空間下的加載
這裏分爲自動加載的類庫層,TP默認爲Controller和Model下的類,這兩個目錄下的類文件會被自動加載
還有一個自定義的自動加載的路徑,通過import方法載入,import方法包含三個參數:
@param string $class 類庫命名空間字符串@param string $baseUrl 起始路徑 @param string $ext 導入的文件擴展名 function import($class, $baseUrl = '', $ext=EXT) {}
這個方法裏包含了加載當前模塊,公共模塊,第三方模塊和其他模塊下的類的引入。並進行了緩存