上節已經把命名空間和目錄的映射都賦值給了Loader的相關屬性了。此時在使用一個不存在的類時,就可以觸發Loader的autoload方法進行自動加載了。
我們看一下上一節執行完成后,Loader類的屬性值情況
```
class Loader {
...
$prefixLengthsPsr4 = [
"t" => [
"think\composer\" => 15,
"think\" => 6 ,
"traits\" => 7
],
"a" => [ "app\" => 4 ]
]
$prefixDirsPsr4 = [
"think\\composer\\" => " /Users/lihui/Documents/tp/tp5.1/vendor/composer/../topthink/think-installer/src ",
"app\\" => "/Users/lihui/Documents/tp/tp5.1/vendor/composer/../../application",
"think\\" => "/Users/lihui/Documents/tp/tp5.1/thinkphp/library/think",
"traits\\" => "/Users/lihui/Documents/tp/tp5.1/thinkphp/library/traits"
]
$fallbackDirsPsr4 = ["/Users/lihui/Documents/tp/tp5.1/extend"]
...
}
```
## autoload方法實現自動加載
在代碼中使用一個不存在的類時,會觸發autoload方法,首頁會查找$classAlias屬性,是否定義了類的別名。如果定義了類的別名和實際類的映射。則可通過類的別名直接使用該類。**主要是通過php內置函數class_alias函數實現**
```
if (isset(self::$classAlias[$class])) {
return class_alias(self::$classAlias[$class], $class);
}
```
若沒有定義類的別名和實際類的映射,則需要走命名空間的映射來找到實際類,并加載。
```
// 查找 PSR-4
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
$first = $class[0];
if (isset(self::$prefixLengthsPsr4[$first])) {
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// 查找 PSR-4 fallback dirs
foreach (self::$fallbackDirsPsr4 as $dir) {
if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
```
最終找到文件在系統中的位置,然后調用include 加載文件。
```
__include_file($file);
return true;
```