
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目录等功能
文章来源: Loader.php --- ThinkPHP5源码分析人吐槽 | 人点赞 |
发表评论