ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## base.php 框架base.php文件,首先载入Loader类,并执行Loader的静态方法register,进行注册自动加载 ``` // 载入Loader类 require __DIR__ . '/library/think/Loader.php'; // 注册自动加载 Loader::register(); ``` 可以自定义加载函数,并有register参数传入。 ``` public static function register($autoload = '') { // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true') } ``` ## Loader.php 由base.php中调用Loader的register静态方法。该方法首先注册一个自动加载函数。接着将框架的aplication,extend,composer的目录和各自的命名空间相映射 #### 注册自动加载 ``` // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); ``` #### composer自动加载支持 获取composer目录 ``` $rootPath = self::getRootPath(); // 项目的根目录 self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR; ``` 载入composer自动加载文件,并将composer下载的安装包关系映射赋值给Loader属性。 $prefixLengthsPsr4,$prefixDirsPsr4两个属性描述了命名空间和实际目录位置的映射。**当通过composer进行下载安装包时,会自动更新composer的autoload_static.php的属性** ``` // Composer自动加载支持 if (is_dir(self::$composerPath)) { if (is_file(self::$composerPath . 'autoload_static.php')) { require self::$composerPath . 'autoload_static.php'; // get_declared_classes函数获取当前所有载入的类 $declaredClass = get_declared_classes(); $composerClass = array_pop($declaredClass); foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) { // 将composer的autoload_static.php类的prefixLengthsPsr4,prefixDirsPsr4属性赋值给Loader的prefixLengthsPsr4, prefixDirsPsr4属性 if (property_exists($composerClass, $attr)) { self::${$attr} = $composerClass::${$attr}; } } } else { self::registerComposerLoader(self::$composerPath); } } ``` 由于composer的autoload_static.php中只定义了`think\composer` `app`和其他通过composer安装的安装包命名空间对于的目录的映射。所以还需要把框架核心的`think``traits`命名空间的映射添加到Loader的$prefixLengthsPsr4,$prefixLengthsPsr4的属性上 ``` // 注册命名空间定义 self::addNamespace([ 'think' => __DIR__, 'traits' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'traits', ]); ``` 将类库的映射文件中的数据,载入到Loader属性$classMap。类库映射文件是需要手动生成的,里面是所有类名映射到类的绝对地址。 ``` // 加载类库映射文件 if (is_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')) { self::addClassMap(__include_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')); } ``` extend扩展目录的位置赋值给Loader类的$fallbackDirsPsr4。若自定义目录也想要自动加载。可以参考extend的方式。 ``` // 自动加载extend目录 self::addAutoLoadDir($rootPath . 'extend') ``` 最后在base.php文件中注册了类的别名。在使用一个不存在的类时,优先判断是否包含类的别名,在根据类的别名所对应的类来加载。 ``` base.php ... // 注册类库别名 Loader::addClassAlias([ 'App' => facade\\App::class, 'Build' => facade\\Build::class, 'Cache' => facade\\Cache::class, 'Config' => facade\\Config::class, 'Cookie' => facade\\Cookie::class, 'Db' => Db::class, 'Debug' => facade\\Debug::class, 'Env' => facade\\Env::class, 'Facade' => Facade::class, 'Hook' => facade\\Hook::class, 'Lang' => facade\\Lang::class, 'Log' => facade\\Log::class, 'Request' => facade\\Request::class, 'Response' => facade\\Response::class, 'Route' => facade\\Route::class, 'Session' => facade\\Session::class, 'Url' => facade\\Url::class, 'Validate' => facade\\Validate::class, 'View' => facade\\View::class, ]); ``` 到此,相关命名空间和目录的映射都准备好了。