众所周知 composer
是现代 PHP 项目的基石, 与古老的 pear
不同, composer
并不是一款专注于系统级别 php 管理的包管理系统,而是基于项目的一个库管理系统。这就好比 npm install -g
和 npm install
的区别。而且最主要的是 pear
不太能跟上时代的潮流,在大家都在用 psr-*
的时候 pear
依然我行我素自成一体。
好吧,可能这是好事,但是也是坏事。好事是很多优秀的包都从 pear
发家致富,比如 PHP_CodeSniffer
, PHP_Unit
等等。但是随着时代的发展,php社区也渐渐地从其他社区汲取到了一些精华,慢慢地向前发展。最近的 laravel
就是直接扔进了 composer
。因为 psr-4
这个规范真是不能再爽更多。这真的是我用各种包用得最顺手的一套命名规范了。
扯远了,扯回 vendor/composer/autoload_real.php
这个核心 composer
文件。
--laravel 学院
总体来说 composer 提供了几种自动加载类型
- classmap
- psr-0
- psr-4
- files
这几种自动加载都会用到,理论上来说,项目代码用 psr-4
自动加载, helper
用 files
自动加载,development
相关用 classmap
自动加载。 psr-0
已经被抛弃了,不过有些历史遗留依然在用,所以偶尔也会看到。
autoload_real.php
好了看了所有的 autoload 类型那么直接怒看一发实现。
首先映入眼帘的就是一坨,我的是这样的
ComposerAutoloaderInit64c47026c93126586e44d036738c0862
为啥?
因为这个类是全局的啊少年。
作为模块化大行其道的今天,全局的类总是有那么点奇怪。为了不让这个 autoload 的 helper 污染全局,composer 的仁兄们还是绞尽脑汁怒弄了这么一个奇怪的 hash。这直接就逼迫广大二笔程序员们不要跟这个撞衫。
可以看到 psr-4 或者 psr-0 的自动加载都是一件很累人的事儿。基本是个 O(n2)
的复杂度。另外有一大堆 is_file
之类的 IO 操作所以性能堪忧。
所以给出的解决方案就是空间换时间。
Compsoer\ClassLoader
会优先查看 autoload_classmap
中所有生成的注册类。如果在classmap
中没有发现再 fallback 到 psr-4 然后 psr-0
所以当打了 composer dump-autoload -o
之后,composer 就会提前加载需要的类并提前返回。这样大大减少了 IO 和深层次的 loop。
1、autoload.PHP
要使用Composer的自动加载,首先需要引入该文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2、autoload_real.php
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
3、ClassLoader.php (部分核心代码)
① PSR-0 规则
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
② PSR-4规则
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
③ Class-map方式
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
什么时候才会去调用上述注册的loadClass函数呢?举例来说
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
至此Composer自动加载流程已讲述完毕。具体的代码还需各位自己去研究。不得不惊叹,有了Composer真是太方便了!