前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tp5源码解析--自动加载类

tp5源码解析--自动加载类

作者头像
高久峰
发布2023-09-18 16:09:32
2110
发布2023-09-18 16:09:32
举报

在TP5的框架使用过程中,自动加载类是可能会接触到,上手不难,但若想随心所欲的用,还是需要了解一番。用了千次,却没看过一次源码,学习源码,起码对TP5这个框架使用更加得心应手,毕竟技术服务于业务,能够写出更简介、更方便、更有效的业务代码,本身就是一件身心愉悦的事儿;

自动加载流程

tp5自动加载
tp5自动加载

第一步,TP框架初始化

Loader会走如下逻辑; 加载autoload_static.php中的 prefixLengthsPsr4prefixDirsPsr4两个数组;

代码语言:javascript
复制
 public static $prefixLengthsPsr4 = array (
        't' => 
        array (
            'think\\composer\\' => 15,
            'think\\' => 6,
        ),
        'a' => 
        array (
            'app\\' => 4,
        ),
    );

    public static $prefixDirsPsr4 = array (
        'think\\composer\\' => 
        array (
            0 => __DIR__ . '/..' . '/topthink/think-installer/src',
        ),
        'think\\' => 
        array (
            0 => __DIR__ . '/../..' . '/thinkphp/library/think',
        ),
        'app\\' => 
        array (
            0 => __DIR__ . '/../..' . '/application',
        ),
    );

PHP

Copy

再通过self::${$attr} = $composerClass::${$attr} 变成当前类的静态数组

详细逻辑如下:

代码语言:javascript
复制
   // Composer 自动加载支持
        if (is_dir(VENDOR_PATH . 'composer')) {
            if (PHP_VERSION_ID >= 50600 && is_file(VENDOR_PATH . 'composer' . DS . 'autoload_static.php')) {
			//引入'autoload_static.php;
                require VENDOR_PATH . 'composer' . DS . 'autoload_static.php';
				//获取全部对象
                $declaredClass = get_declared_classes();
				//弹出最后一个对象类 也就是autoload_static.php
                $composerClass = array_pop($declaredClass);
		//查看autoload_static.php对象数组
                foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) {
                    if (property_exists($composerClass, $attr)) {
					//转化成自己类的静态数组
                        self::${$attr} = $composerClass::${$attr};
                    }
                }
            } else {
			//加载Psr0方法
                self::registerComposerLoader();
            }
        }

        // 注册命名空间定义
        self::addNamespace([
            'think'    => LIB_PATH . 'think' . DS,
            'behavior' => LIB_PATH . 'behavior' . DS,
            'traits'   => LIB_PATH . 'traits' . DS
        ]);

        // 加载类库映射文件
        if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {
            self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
        }

        self::loadComposerAutoloadFiles();

        // 自动加载 extend 目录,可以在这里加相关目录,拓展包就是在这手动放入 extend中加载
        self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);

PHP

Copy

第二步 new class()

当一个class不存在走自动加载方法; spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true) 通过spl_autoload_register 走autoload($class)方法; autoload($class)->检测命名空间别名->通过上一步初始化生成的静态化数组查找相关class文件是否存在->返回对像(结束);

代码语言:javascript
复制
 public static function autoload($class)
    {

        // 检测命名空间别名
        if (!empty(self::$namespaceAlias)) {
            $namespace = dirname($class);
            if (isset(self::$namespaceAlias[$namespace])) {
                $original = self::$namespaceAlias[$namespace] . '\\' . basename($class);
                if (class_exists($original)) {
                    return class_alias($original, $class, false);
                }
            }
        }
//查看文件
        if ($file = self::findFile($class)) {
            // 非 Win 环境不严格区分大小写
            if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) {
			//引入文件
                __include_file($file);
                return true;
            }
        }

        return false;
    }

PHP

Copy

其中核心方法

代码语言:javascript
复制
    public static function register($autoload = null)
    {
		 // 注册系统自动加载
        spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
	}

PHP

Copy

TP自动加载方法

tp自动加载方法
tp自动加载方法

composer自动方法

composer自动加载
composer自动加载

其实两个自动加载打通小异; Tp在加载方法,个人认为是借鉴composer;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一步,TP框架初始化
    • 再通过self::${$attr} = $composerClass::${$attr} 变成当前类的静态数组;
    • 第二步 new class()
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档