ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
:-: 自动加载 ~~~ /** * 类名映射信息 * @var array */ protected static $map = []; /** * 类库别名 * @var array */ protected static $classAlias = []; /** * PSR-4 * @var array */ private static $prefixLengthsPsr4 = []; private static $prefixDirsPsr4 = []; private static $fallbackDirsPsr4 = []; /** * PSR-0 * @var array */ private static $prefixesPsr0 = []; private static $fallbackDirsPsr0 = []; /** * 自动加载的文件列表 * @var array */ private static $autoloadFiles = []; /** * Composer安装路径 * @var string */ private static $composerPath; ~~~ #### 自动加载 ~~~ // 注册自动加载机制 public static function register($autoload = '') { // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); // 注册命名空间定义 self::addNamespace([ 'think' => __DIR__ . '/', 'traits' => __DIR__ . '/../traits/', ]); $path = dirname($_SERVER['SCRIPT_FILENAME']); if (is_file('./think')) { $rootPath = realpath($path) . '/'; } else { $rootPath = realpath($path . '/../') . '/'; } // 加载类库映射文件 if (is_file($rootPath . 'runtime/classmap.php')) { self::addClassMap(__include_file($rootPath . 'runtime/classmap.php')); } self::$composerPath = $rootPath . 'vendor/composer/'; // Composer自动加载支持 if (is_dir(self::$composerPath)) { self::registerComposerLoader(self::$composerPath); } // 自动加载extend目录 self::addAutoLoadDir($rootPath . 'extend'); } // 自动加载 public static function autoload($class) { if (isset(self::$classAlias[$class])) { return class_alias(self::$classAlias[$class], $class); } if ($file = self::findFile($class)) { // Win环境严格区分大小写 if (strpos(PHP_OS, 'WIN') !== false && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) { return false; } __include_file($file); return true; } } ~~~ [spl_autoload_register](http://php.net/manual/zh/function.spl-autoload-register.php) — 注册给定的函数作为 __autoload 的实现 ;将函数注册到SPL __autoload函数队列中。如果该队列中的函数尚未激活,则激活它们。 [`pathinfo`](http://www.php.net/pathinfo) — 返回文件路径的信息 `spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);` 自动加载运行了 `autoload` 函数 [`$_SERVER['SCRIPT_FILENAME']`](http://php.net/manual/zh/reserved.variables.server.php)当前执行脚本的绝对路径。 [realpath](http://php.net/manual/zh/function.realpath.php) — 返回规范化的绝对路径名;realpath() 扩展所有的符号连接并且处理输入的 path 中的 '/./', '/../' 以及多余的 '/' 并返回规范化后的绝对路径名。返回的路径中没有符号连接,'/./' 或 '/../' 成分。 `self::addAutoLoadDir($rootPath . 'extend');` 设置 extend 文件目录为附加配置目录 ~~~ // 添加Ps0空间 private static function addPsr0($prefix, $paths, $prepend = false) { if (!$prefix) { if ($prepend) { self::$fallbackDirsPsr0 = array_merge( (array) $paths, self::$fallbackDirsPsr0 ); } else { self::$fallbackDirsPsr0 = array_merge( self::$fallbackDirsPsr0, (array) $paths ); } return; } $first = $prefix[0]; if (!isset(self::$prefixesPsr0[$first][$prefix])) { self::$prefixesPsr0[$first][$prefix] = (array) $paths; return; } if ($prepend) { self::$prefixesPsr0[$first][$prefix] = array_merge( (array) $paths, self::$prefixesPsr0[$first][$prefix] ); } else { self::$prefixesPsr0[$first][$prefix] = array_merge( self::$prefixesPsr0[$first][$prefix], (array) $paths ); } } // 添加Psr4空间 private static function addPsr4($prefix, $paths, $prepend = false) { if (!$prefix) { // Register directories for the root namespace. if ($prepend) { self::$fallbackDirsPsr4 = array_merge( (array) $paths, self::$fallbackDirsPsr4 ); } else { self::$fallbackDirsPsr4 = array_merge( self::$fallbackDirsPsr4, (array) $paths ); } } elseif (!isset(self::$prefixDirsPsr4[$prefix])) { // Register directories for a new namespace. $length = strlen($prefix); if ('\\' !== $prefix[$length - 1]) { throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length; self::$prefixDirsPsr4[$prefix] = (array) $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. self::$prefixDirsPsr4[$prefix] = array_merge( (array) $paths, self::$prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. self::$prefixDirsPsr4[$prefix] = array_merge( self::$prefixDirsPsr4[$prefix], (array) $paths ); } } ~~~ #### 文件加载 ~~~ // 自动加载 public static function autoload($class) { } include 加载文件 ~~~ [`class_alias`](http://php.net/manual/zh/function.class-alias.php) — 为一个类创建别名 `registerComposerLoader($composerPath)` 函数加载 `vendor/composer/` 下的Composer文件 `addAutoLoadDir` 函数加载 `extend` 下的配置文件 因为 使用了 注册系统自动加载 `spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);` 所以 在引用Loader 之后的操作都会自动运行 `autoload` 方法 进行 `PSR` 加载 `think` 目录下的文件 例如: `A:b(); // 运行think 目录下 A.php 文件类的 b(); 方法`