ThinkPHP5框架的自动注册加载流程如下:
 
在base.php文件中,用一句代码 \think\Loader::register(); 实现自动加载机制的注册。
// 载入Loader类
require CORE_PATH . 'Loader.php';
 
// 注册自动加载
\think\Loader::register();
 
// 注册错误和异常处理机制
\think\Error::register();
 
为什么要使用自动加载呢,这是因为自动加载机制可以把主目录下的所有的类一次性全部加载进来,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,只要这些类能在主目录下找到,类在使用前就会被加载。
TP5中,自动加载的实现由think\Loader类库完成,自动加载规范符合PHP的PSR-4。
 
打开library/think/Loader.php,先看Loader类的register方法,核心代码如下:
首先进行的是注册系统自动加载,因为参数$autoload默认为空,所以 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); 这句代码可以简化为 spl_autoload_register('think\\Loader::autoload'); ,其作用是保证Loader类的加载。
一开始还觉得已经在base.php中引入Loader类了,为什么还要使用spl_autoload_register()函数注册自动加载呢?在base.php中看到注册自动加载后面是注册错误和异常处理机制,即 \think\Error::register(); ,使用的是think命名空间下Error类的register静态方法,而base.php并没有引入Error类文件,有了这个自动加载器,便可以在spl_autoload_register()函数指定的autoload()函数中得到一个参数think\Error,通过该函数来加载对应的类文件。autoload()函数先处理命名空间别名,然后通过findFile()函数处理映射关系得到真实的路径,最后加载文件。
 
加载完相关的类文件后,register()函数通过addNameSpace()函数注册命名空间和路径的关联,该函数中调用了addPsr4()函数,得到的结果是一个变量self::$prefixLengthsPsr4的数组:
// self::$prefixLengthsPsr4 PSR-4 命名空间前缀长度映射
Array
(
    [t] => Array
        (
            [think\] => 6
            [traits\] => 7
        )
    [b] => Array
        (
            [behavior\] => 9
        )
)
 
接着register()函数通过addClassMap()注册类名映射,数组合并到\$map,字符串关联到$class,如果/runtime/classmap.php文件存在,就加载类库映射文件;通过rigisterComposerLoader()注册composer的自动加载,如果/vendor/composer目录存在,就进行composer的自动加载;最后加载extend目录,整个框架的自动加载就完成了。

ThinkPHP5.0源码学习之注册自动加载的更多相关文章

  1. ThinkPHP5.0源码学习之注册错误和异常处理机制

    在base.php文件中,用一句代码\think\Error::register();实现错误和异常处理机制的注册. // 注册错误和异常处理机制 \think\Error::register(); ...

  2. ThinkPHP5.0源码学习之框架启动流程

    ThinkPHP5框架的启动流程图如下: ThinkPHP5的启动流程按照文件分为三步: 1.请求入口(public/index.php) 2.框架启动(thinkphp/start.php) 3.应 ...

  3. ThinkPHP5.0源码学习之缓存Cache(一)

    一.文件 1.缓存配置文件:thinkphp\convention.php 2.缓存文件:thinkphp\library\think\Cache.php 3.驱动目录:thinkphp\librar ...

  4. ThinkPHP5.0源码学习之执行应用

    一.应用启动 在/thinkphp/start.php文件中,用一句代码App::run()->send();实现应用的启动. // 执行应用 App::run()->send();   ...

  5. spring源码学习之bean的加载(三)

    接着二中的继续写,那个都超过1000行了,哈,需要重新写一个,要不太长了,我都看不下去了 7.4 初始化bean doCreateBean函数中有这样一行代码:这行代码中initializeBean函 ...

  6. spring源码学习之bean的加载(二)

    这是接着上篇继续写bean的加载过程,好像是有点太多了,因为bean的加载过程是很复杂的,要处理的情况有很多,继续... 7.创建bean 常规的bean的创建时通过doCreateBean方法来实现 ...

  7. 【requireJS源码学习02】data-main加载的实现

    前言 经过昨天的学习,我们大概了解到了requireJS的主要结构,这里先大概的回顾一下 首先从总体结构来说,require这里分为三块: ① newContext之前变量声明或者一些工具函数 ② n ...

  8. spring源码学习之bean的加载(一)

    对XML文件的解析基本上已经大致的走了一遍,虽然没有能吸收多少,但是脑子中总是有些印象的,接下来看下spring中的bean的加载,这个比xml解析复杂的多.这个加载,在我们使用的时候基本上是:Bea ...

  9. ThinkPHP5.0源码学习之缓存Cache(二)

    一.使用Cache类 TP5.0框架默认使用的是File文件缓存驱动,可以修改全局配置文件convention.php中的type,将其改为Redis,这样使用的就是Redis缓存驱动了.

随机推荐

  1. 1、jeecg 笔记开篇

    1. 前言 终究还是入了 jeecg 的 "坑",国庆后公司采用该框架开发,故开篇记录. 虽说入"坑",但不得不承认 jeecg 确实是一个非常强大的平台. 其 ...

  2. .net core使用ef core操作mysql数据库

    新建.net core webapi项目 在NuGet包管理器中搜索 MySql.Data.EntityFrameworkCore并安装,安装的8.0.14版本,只安装这一个就够了 安装后创建Data ...

  3. 在Windows上搭建Git Server

    Git在版本控制方面,相比与SVN有更多的灵活性,对于开源的项目,我们可以托管到Github上面,非常方便,但是闭源的项目就会收取昂贵的费用. 那么私有项目,如何用Git进行代码版本控制呢?我们可以自 ...

  4. JDK 1.8源码阅读 TreeMap

    一,前言 TreeMap:基于红黑树实现的,TreeMap是有序的. 二,TreeMap结构 2.1 红黑树结构 红黑树又称红-黑二叉树,它首先是一颗二叉树,它具体二叉树所有的特性.同时红黑树更是一颗 ...

  5. 【Mac】-NO.100.Mac.1.java.1.001-【Mac Install multiple JDK】-

    Style:Mac Series:Java Since:2018-09-10 End:2018-09-10 Total Hours:1 Degree Of Diffculty:5 Degree Of ...

  6. JavaScriptDom和应用

    DOM编程 DOM是Document Object Model文档对象模型 DOM是一种与浏览器,平台,语言无关的接口,使得你可以访问页面其他的标准组件 DOM简介 D:文档  –  html 文档 ...

  7. HBase 笔记2

    Hadoop 服务启动顺序: zookeeper ->journalnode->namenode -> zkfc -> datanode HBase Master WEB控制台 ...

  8. crontab定时

    yum install -y vixie-cron --安装定时服务 每分钟更新一次商品crontab -e* * * * * /usr/bin/curl http://test.wadao.com/ ...

  9. GoldenGate BR(bounded Recovery)简单说明

    背景 Oracle数据库的在线日志包含已提交的和未提交的事务,但OGG只会将已提交的事务写入到队列文件.因此,针对未提交的事务,特别是未提交的长事务,OGG会怎样处理呢? 有些长事务是在批处理作业中, ...

  10. Python3 批量更改文件后缀名

    Python3 批量更改文件后缀名 示例: # coding:utf8 import os import sys def Rename(): #Path = "F:\\test\\" ...