Loader.php --- ThinkPHP5源码分析

Loader.php — ThinkPHP5源码分析

最近开始了解ThinkPHP5框架,有很多基础知识需要学习,所以打算将自己学习笔记记录下来,即可以和大家分享,也可以方便自己以后回顾知识。由于只是个人笔记,便不是详细的教程,有不懂的地方还请自行百度。

调试工具

  • PHPStorm 2018.1.1
  • Xdebug 2.6.0

开发环境

  • ThinkPHP ‌5.0.16
  • PHP 7.1.13-nts
  • Apache 2.4.23
  • MySQL 5.6.39

项目目录

project  应用部署目录
├─application           应用目录(可设置)
│  ├─common             公共模块目录(可更改)
│  ├─index              模块目录(可更改)
│  │  ├─config.php      模块配置文件
│  │  ├─common.php      模块函数文件
│  │  ├─controller      控制器目录
│  │  ├─model           模型目录
│  │  ├─view            视图目录
│  │  └─ ...            更多类库目录
│  ├─command.php        命令行工具配置文件
│  ├─common.php         应用公共(函数)文件
│  ├─config.php         应用(公共)配置文件
│  ├─database.php       数据库配置文件
│  ├─tags.php           应用行为扩展定义文件
│  └─route.php          路由配置文件
├─extend                扩展类库目录(可定义)
├─public                WEB 部署目录(对外访问目录)
│  ├─static             静态资源存放目录(css,js,image)
│  ├─index.php          应用入口文件
│  ├─router.php         快速测试文件
│  └─.htaccess          用于 apache 的重写
├─runtime               应用的运行时目录(可写,可设置)
├─vendor                第三方类库目录(Composer)
├─thinkphp              框架系统目录
│  ├─lang               语言包目录
│  ├─library            框架核心类库目录
│  │  ├─think           Think 类库包目录
│  │  └─traits          系统 Traits 目录
│  ├─tpl                系统模板目录
│  ├─.htaccess          用于 apache 的重写
│  ├─.travis.yml        CI 定义文件
│  ├─base.php           基础定义文件
│  ├─composer.json      composer 定义文件
│  ├─console.php        控制台入口文件
│  ├─convention.php     惯例配置文件
│  ├─helper.php         助手函数文件(可选)
│  ├─LICENSE.txt        授权说明文件
│  ├─phpunit.xml        单元测试配置文件
│  ├─README.md          README 文件
│  └─start.php          框架引导文件
├─build.php             自动生成定义文件(参考)
├─composer.json         composer 定义文件
├─LICENSE.txt           授权说明文件
├─README.md             README 文件
├─think                 命令行入口文件

Loader类路径:thinkphp\library\think\Loader.php

Loader.php结构图

image

代码介绍

该类主要通过调用Loader::register()方法实现了调用对象或方法时自动加载文件,按照统一的PSR-0或PSR-4规范进行引用。

自定义自动加载机制主要是用到了spl_autoload_register方法,注册自定义加载函数,从而实现调用命名空间中的类或方法时自动加载php文件

public static function register($autoload = null)
{
 // 注册系统自动加载
    // 自动加载关键配置,对调用对象会自动按规范引用对象文件
    spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
    ...
}

Loader::autoload()主要通过Loader::findFile()根据类名全称查找文件位置并且引用

public static function autoload($class)
{
    ...
    if ($file = self::findFile($class)) {
        // 非 Win 环境不严格区分大小写
        if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) {
            __include_file($file);
            return true;
        }
    }
    ...
}

private static function findFile($class)
{
    // 类库映射
    if (!empty(self::$map[$class])) {
        return self::$map[$class];
    }

    // 查找 PSR-4
    $logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
    $first           = $class[0]; // 获取prefixLengthsPsr4对应下标

    if (isset(self::$prefixLengthsPsr4[$first])) {
        foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
            if (0 === strpos($class, $prefix)) { // 判断类的命名空间
                foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
                    // 判断类的文件路径
                    // 通过$prefixLengthsPsr4的值截取类文件名
                    if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) {
                        return $file;
                    }
                }
            }
        }
    }

    // 查找 PSR-4 fallback dirs
    // $fallbackDirsPsr4 其他的命名空间位置
    foreach (self::$fallbackDirsPsr4 as $dir) {
        if (is_file($file = $dir . DS . $logicalPathPsr4)) {
            return $file;
        }
    }

    ...
}

function __include_file($file)
{
    return include $file;
}

Loader::register()方法还实现了Composer自动加载支持、注册框架内置命名空间、加载类库映射文件、加载composer autofile文件、自动加载extend目录等功能

你可能感兴趣的:(thinkphp)