多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
首先我们拿到框,肯定要先找到框架的入口文件,Thinkphp5.1的入口文件 `tp5_analyze\public\index.php` ``` <?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st <liu21st@gmail.com> // +---------------------------------------------------------------------- // [ 应用入口文件 ] namespace think; // 加载基础文件 require __DIR__ . '/../thinkphp/base.php'; // 支持事先使用静态方法设置Request对象和Config对象 // 执行应用并响应 Container::get('app')->run()->send(); ``` 我们可以看到在入口文件中,他会去加载基础文件 `thinkphp/base.php` ,基础文件所在目录 `tp5_analyze\thinkphp\base.php` ``` <?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st <liu21st@gmail.com> // +---------------------------------------------------------------------- namespace think; // 载入Loader类 require __DIR__ . '/library/think/Loader.php'; // 注册自动加载 Loader::register(); // 注册错误和异常处理机制 Error::register(); // 实现日志接口 if (interface_exists('Psr\Log\LoggerInterface')) { interface LoggerInterface extends \Psr\Log\LoggerInterface {} } else { interface LoggerInterface {} } // 注册类库别名 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, ]); ``` 在`base.php`中会去加载`Loader.php`这个文件或者说是类,这个类可以这么说,就是Thinkphp5自动加载的灵魂。可以看到加载的类 `Loader.php`,类所在目录`thinkphp\library\think\Loader.php`,这个类库就是Thinkphp5封装的底层基础类库,这个类库就是需要我们进行深度分析的类库。 我们可以看到,在`base.php`中加载完`Loader.php`之后,会调用`Loader::register();`方法,我们追踪进去可以看到这个方法 ~~~ // 注册自动加载机制 public static function register($autoload = '') { // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); $rootPath = self::getRootPath(); self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR; // Composer自动加载支持 if (is_dir(self::$composerPath)) { if (is_file(self::$composerPath . 'autoload_static.php')) { require self::$composerPath . 'autoload_static.php'; $declaredClass = get_declared_classes(); $composerClass = array_pop($declaredClass); foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) { if (property_exists($composerClass, $attr)) { self::${$attr} = $composerClass::${$attr}; } } } else { self::registerComposerLoader(self::$composerPath); } } // 注册命名空间定义 self::addNamespace([ 'think' => __DIR__, 'traits' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'traits', ]); // 加载类库映射文件 if (is_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')) { self::addClassMap(__include_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')); } // 自动加载extend目录 self::addAutoLoadDir($rootPath . 'extend'); } ~~~ 这个方法其实就是注册自动加载的机制。他把Thinkphp的加载与Composer的加载封装到了一个文件,我们可以看到自动加载机制的方法里面,引入了Composer包里面的`autoload_static.php`,并针对Composer的这种方式做自动加载,这里先不啰嗦,我们会在后续的章节中详细了解这个方法。 其他的框架在使用的时候,他们的逻辑是是一样的,都会在框架的第一步实现自动加载。