“Composer是现代php项目的基石,作为一个有梦想的PHPer,不懂可不行哦” ——海盗.娜美
这节是Composer源码分析系列的第二节,我们继续延续上节未完成的工作。上节,我们通过autoload_real.php文件了解self::$loader得到\Composer\Autoload\ClassLoader()对象。然后就将注册到autoload队列的loaderClassLoader自动加载器舍弃。这节,让我们继续composer探险之旅...
在开始之前,我们要了解composer完成了什么工作。
总体来说,composer提供了如下几种加载类型:
  1. classmap
  2. psr-0
  3. psr-4
  4. files
这几种自动加载都会用到,通常,项目代码psr-4自动加载,helper用files自动加载,development相关用classmap自动加载。psr-0已经废弃了,但偶尔也会在项目中看到。
这应该是最最简单的 autoload 模式了。大概的意思就是这样的:
{
    "classmap": ["src/"]
}
composer 在背后就会读取这个文件夹中所有的文件 然后再 vendor/composer/autoload_classmap.php 中怒将所有的class的namespace+classname生成一个key=>value的php数组
<?php
return [
  'App\\Console\\Kernel' => $baseDir . '/app/Console/Kernel.php'
];
?>
然后就可以光明正大地用 spl_autoload_register 这个函数来怒做自动加载了。
好吧,上面的例子其实有点 tricky,仅仅是为了帮助我们理解composer,上面这个 autoload 实际上是根据 prs-4 来生成出来的。不过这不重要,了解底层重要点,我们可以看到所有的所谓的 autoloading 其实可以理解为生成了这么一个 classmap,这是 composer dump-autoload -o 做的事儿。不然的话compoesr 会吭哧吭哧地去动态读取 psr-4 和 prs-0 的内容。
实际上每次我们执行composer update操作时,composer会根据.json文件生成autoload_static.php,该文件中包含了命名空间到实际映射的数组(采用psr4或psr0,中间的转化过程暂且不说)。我们只需要按照一定的自动加载器规则对其进行加载就可以引入实际文件路径,然后光明正大地使用组件类文件中的类啦。
废话少说,让我们继续后面的代码
// PHP版本大于5.6且未定义HHVM_VERSION常量,返回True
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());if ($useStaticLoader) {    // 定义了命名空间,类名与类命名空间之间的映射,同时还提取类名首字母,加快检索速度    require_once __DIR__ . '/autoload_static.php';// 将$loader参数传到类的getInitializer方法call_user_func(\Composer\Autoload\ComposerStaticInit2b0e34f11c87555a88f83f6bf964b679::getInitializer($loader));…

进入该类继续查看

public static function getInitializer(ClassLoader $loader){   // 相当于在ClassLoader类里面加了个静态成员方法    // 通过该方法可以很方便地将ComposerStaticInit中的成员方法传递给另一个类ClassLoader的成员方法,赞!    // 调用getInitializer方法相当于给ClassLoader类增加了成员方法。return \Closure::bind(function () use ($loader) {       // 返回命名空间到实际路径基于ps4组成的数组        $loader->prefixLengthsPsr4 = ComposerStaticInit2b0e34f11c87555a88f83f6bf964b679::$prefixLengthsPsr4;              $loader->prefixDirsPsr4 = ComposerStaticInit2b0e34f11c87555a88f83f6bf964b679::$prefixDirsPsr4;        // 返回命名空间到实际路径基于psr0组成的数组    $loader->prefixesPsr0 = ComposerStaticInit2b0e34f11c87555a88f83f6bf964b679::$prefixesPsr0;}, null, ClassLoader::class);
}
我们,刚刚在外层也看到使用了如何扩充了ClassLoader类的成员方法。
call_user_func(\Composer\Autoload\ComposerStaticInit2b0e34f11c87555a88f83f6bf964b679::getInitializer($loader));
查看该方法剩下的代码
...
$loader->register(true);
if ($useStaticLoader) {    // 返回$files静态数组,该数组存储一段hash到实际文件路径。$includeFiles = Composer\Autoload\ComposerStaticInit2b0e34f11c87555a88f83f6bf964b679::$files;
} else {    $includeFiles = require __DIR__ . '/autoload_files.php’;
}
foreach ($includeFiles as $fileIdentifier => $file) { composerRequire2b0e34f11c87555a88f83f6bf964b679($fileIdentifier, $file);
}
return $loader;

$loader->reigister(true)有效代码

// 注册自动加载器,并将该自动加载器放在队列首部
public function loadClass($class){    // 引入类文件if ($file = $this->findFile($class)) {        includeFile($file);return true;    }
}

CoposerRequirexxxx代码

// 这些文件放在$GLOBALS数组(引用全局作用域的全部变量)。
// $file是文件的实际路径,引用该文件
function composerRequire2b0e34f11c87555a88f83f6bf964b679($fileIdentifier, $file){    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {// 引用        require $file;$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;    }
}

关于Composer的研读,就到此为止啦,有感兴趣的同学可以深入学习下代码细节。柚子会在下节快速切入到Slim核心框架的研读工作中。

参考:http://blog.hans-lizihan.com/php/2015/06/25/php-composer-autoload.html

Slim研读笔记四之Composer(下)相关推荐

  1. linux下I2C驱动发送IO时序,笔记四:linux下IO口模拟实现I2C协议

    一.i2c总线是什么? 1.i2c总线是一种物理总线及实实在在的总线,通过板子pcb等图能看到. 2.i2c总线是一种主从结构. 3.i2c总线是一种通信协议. 4.i2c总线是两线制半双工串行总线: ...

  2. python编程从入门到实践pdf_Python编程入门研读笔记(二)

    <Python的四则运算>是本单元的第二课,本课依然存在许多"坑".请各位老师放心,这些坑我已经帮你踩过了.如果您对我的教材研读笔记有任何意见或建议,请在文章底部留言O ...

  3. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  4. 吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码

    吴恩达<机器学习>学习笔记四--单变量线性回归(梯度下降法)代码 一.问题介绍 二.解决过程及代码讲解 三.函数解释 1. pandas.read_csv()函数 2. DataFrame ...

  5. 《关键对话——注意观察,如何判断对话氛围是否安全》读书笔记(四)

    <关键对话--注意观察,如何判断对话氛围是否安全>读书笔记(四) 在对话过程中,既要关注对话内容(即讨论的主题),也要观察对话气氛(即参与者的反应).越早意识到你和对方退出了对话机制,就越 ...

  6. 《MFC游戏开发》笔记四 键盘响应和鼠标响应:让人物动起来

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9327377 作者:七十一雾央 新浪微博:http:// ...

  7. 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 作者:毛星云(浅墨)    邮箱: happylifemxy@163.com 本篇文章里,我们首先对Direct3D之中固定功能流水线中的 ...

  8. Servlet笔记四(JSP技术)

    本栏博客目录 Serlvet笔记一(Servlet基础) Servlet笔记二(请求和响应) Servlet笔记三(会话及其会话技术) Servlet笔记四(JSP技术) Servlet笔记五(EL表 ...

  9. 【Visual C++】游戏开发笔记四十六 浅墨DirectX教程十四 模板测试与镜面特效专场

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处.   文章链接: http://blog.csdn.net/zhmxy555/article/details/8632184 作者:毛星云( ...

最新文章

  1. 不同品牌发电机组间的并机知识
  2. 中文版开源!最最最经典的Python编程教材强势来袭~
  3. .Net中DataTable的保存
  4. Struts2整合SiteMesh
  5. 前端学习(3195):虚拟dom的创建方式1的js
  6. element-ui upload组件 上传文件类型限制
  7. leetcode18.4Sum
  8. cve-2020-0796_微软SMBv3 Client/Server远程代码执行漏洞简单分析(CVE20200796)
  9. Google 将于明年彻底关闭 Chrome Apps,以后就是 PWA 的天下了
  10. SQL里面也能用Split()
  11. 专业的现场调音机架软件 - Deskew Technologies Gig Performer 4 Mac
  12. 彻底讲明白浅拷贝与深拷贝
  13. 集体智慧编程_6文档过滤
  14. 阿里巴巴分布式调度引擎tbschedule实战四tbschedule的配置使用
  15. linux 设置固定ip的方法
  16. 数据载入、Pandas基础和探索性数据分析
  17. mysql导出一个数据库的结构及遇到的问题
  18. 08canvas画图
  19. 简单爬取红牛分公司基本数据part01
  20. 2020-10-18大二第七周

热门文章

  1. mavsdk_api
  2. 【硬刚大数据】大数据同步工具之FlinkCDC/Canal/Debezium对比
  3. Android游戏自动化性能测试 - 王者荣耀测试实例
  4. 1. 定义、功能和目标
  5. iOS中进行数据压缩
  6. Camunda DMN
  7. font-size: 62.5%的意义
  8. 2023年做前端还是WebGIS?
  9. Eslint快速入门和使用技巧-教程
  10. Keras 入门基础知识+完整实例