美文网首页
TP5源码:类的自动加载

TP5源码:类的自动加载

作者: 机智的老刘明同志 | 来源:发表于2019-07-26 07:52 被阅读0次

准备工作:

        1.tp5.0.24核心版源码一份

        2.了解函数  spl_autoload_register(autoload_function,throw,prepend)的作用

        (类似与__autoload(),但是__autoload()只能指定一个函数,而spl_autoload_register可以注册多个函数来处理这个逻辑。一旦业务复杂 __autoload()就完全不能胜任。)

        3 PSR4:知道是文件路径载入规范就行了

为什么要实现类的自动加载?

        一个项目如果头部写上很多require和include会很麻烦。为了使得没有include或者require类的时候也正常new一个类,所以有了自动加载的概念。

        spl_autoload_register函数就可以实现上面说的功能

类的自动加载实现:

        从public目录下开始一步一步向后查找。public/index.php -> start.php -> base.php -> Loader.php

        register方法就是我们实现 类的自动加载的关键

        从下图我们可以看出 tp5把 系统自动加载的类 和 composer自动加载的类 分成两个部分去处理

        为了支持 composer 拓展,在自动注册时候,把composer 也顺带一起注册了,方便对拓展的调用。

        由于autoload_static.php 文件中的类名一直在变化,我们无法得到固定的类名(我也不懂为什么要变化)

        为了把autoload_static.php中 的属性 载入进程序中,在这里他们换了一种形式

        $declaredClass = get_declared_classes();  (得到所有已定义的类名)

        $composerClass = array_pop($declaredClass); (最后一个类就是autoload_static.php)

        接下来,我们看看autoload_static.php中内容

        PSR4 标准是用顶级命名空间目录替换顶级命名空间

        具体说明上面两个数组的作用:

        假如我们找 think \ composer \ liuming  这个命名空间,通过前缀索引和字符串匹配我们得到了

        'think\\composer\\' => 15,

        'think\\composer\\' =>

            array (

                0 => __DIR__ . '/..' . '/topthink/think-installer/src',

            ),

        然后我们就可以将命名空间  think \ composer \ liuming  前15个字符替换成目录 __DIR__ . '/..' . '/topthink/think-installer/src,我们就得到了__DIR__ . '/..' . '/topthink/think-installer/src/liuming  .php,先验证磁盘上这个文件是否存在,如果不存在接着遍历。如果遍历后没有找到,则加载失败。

        注册命名空间定义

        没什么说的,就是把所需要用到的类,映射到Psr4空间这个静态变量中。到时候方便我们使用命名空间进行调用。

        加载类库映射文件

        在 TP5 代码下执行php think optimize:autoload 就会在runtime下生成 classmap.php 文件,生成的类库映射文件会扫描系统目录和应用目录的类库。在之后碰到了之后直接拿来用,提高系统自动加载的性能。文件形式如下:

        自动加载 extend 目录        

        self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);

         实际上就是把extend下面的类塞到fallbackDirsPsr4这个数组中

        综上我们得到了四个数组!整理如下


autoload ()方法详解:

        1.调用think\\Loader::autoload()

        2.autoload()中检测命名空间的别名

        3  没有找到命名空间的映射,调用findFile方法

        在findFile方法中,我们用到了上面提到的四个数组

        在classMap中找类库映射(所以说生成classMap文件省略了后面查找过程,可以提升框架运行速度)

        在这两个数组中拿到 命名空间长度,并将对应命名空间替换成真正的文件路径

        顺带去extend中找下。

补充:

        通过composer安装的类会在 autoload_static中自动增加映射。

        因此如果是手动粘贴复制,则需要在其中增加映射

相关文章

网友评论

      本文标题:TP5源码:类的自动加载

      本文链接:https://www.haomeiwen.com/subject/mqbhrctx.html