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

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

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

自动加载流程

第一步,TP框架初始化

Loader会走如下逻辑;

加载autoload_static.php中的 prefixLengthsPsr4prefixDirsPsr4两个数组;

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',
        ),
    );


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

详细逻辑如下:

// 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);

第二步 new class()

当一个class不存在走自动加载方法; spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true) 通过spl_autoload_register 走autoload($class)方法;

autoload($class)->检测命名空间别名->通过上一步初始化生成的静态化数组查找相关class文件是否存在->返回对像(结束);

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;
    }


其中核心方法

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


TP自动加载方法

composer自动方法

其实两个自动加载打通小异;

Tp在加载方法,个人认为是借鉴composer;

目录
相关文章
|
12月前
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
455 0
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1135 29
|
12月前
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
511 5
|
12月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
482 4
|
12月前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
376 1
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
存储 前端开发 JavaScript
在线教育网课系统源码开发指南:功能设计与技术实现深度解析
在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
466 2
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。

热门文章

最新文章

推荐镜像

更多
  • DNS