本文仅仅关注composer的自动加载。
我们以yii2为例,当我们通过composer生成了一个yii2程序后,会在vendor下建立一个autoload.php文件,它负责帮我们自动加载vendor内的各种库(yii2核心库也在vendor内,你懂得!)。
而你一定知道yii2的入口文件index.php有一行。
require(__dir__ . '/../vendor/autoload.php');
由此可见,yii2对composer的友好程度,也难怪~孤木不成林,yii2也要靠无数个composer扩展枝干才能变成参天大树。
下面开始正式讲解composer的autoload,告诉你各式各样扩展安装后,我们并没有使用include / require,那么composer是如何帮我们找到他们的那?
目前为止,composer一共支持4种自动加载方式
psr-0psr-4class-map直接包含file
这四种方式足以让composer涵盖地球上所有的php第三方扩展库。
psr是一套php开发标准,现在大多数主流框架都在支持,工兵连已经开专题分享psr干货。
psr-4
psr-4是composer推荐使用的一种方式,因为它更易使用并能带来更简洁的目录结构。在一个扩展的composer.json里是这样进行配置的:
{ "autoload": { "psr-4": { "foo\\": "src/", } }}
key和value就定义出了namespace以及其对应的目录映射。按照psr-4的规则,当试图自动加载"foo\bar\baz"类的使用,会去寻找"srcbarbaz.php"这个文件,如果它存在则加载,要注意的是此时"foo\"并不会出现在文件路径中。
而composer.json这样的配置会被composer转换成namespace与文件目录的map形式,并存在vendor/composer/autoload_psr4.php文件中,所以如果你安装的某个扩展自动加载是psr-4形式,你可以在autoload_psr4.php找到它的真实路径。
psr-0
这是一个已经过时的标准,那是在遥远的php5.2时代,你我都知道,php5.3之后才有了类似namespace这样的高级属性,所以psr-0更多是考虑<=5.2时代的扩展,于是乎psr组织用了一个伪namespace的做法。
有点蒙圈么?那我们来看代码你就明白了。
{ "autoload": { "psr-0": { "foo\\": "src/", } }}
我们来分析这个扩展的加载方式,什么是伪namespace那?当我们用这个库的时候
$model = new foo_bar_baz();
对的,psr-0的时代,有很多以下划线分隔的类名,它代表。。。它代表。。。
src/foo/bar/baz.php
聪明的你一定明白什么是伪namespace了吧,通过命名的下划线来映射目录结构。
哎,那个时代的标准制定者们也真心不容易呀。
class-map方式
{ "autoload": { "classmap": ["src/", "lib/"] } }
这个加载方式比较容易理解,当composer开始安装扩展的时候,会根据composer.json里的这个 autoload 告诉的方式classmap,来遍历src、lib目录然后将里面的类文件和其路径一一对应,存放到vendor/composer/autoload_classmap.php内。
例如src/下有一个basecontroller类,那么在autoload_classmap.php文件中,就会生成这样的配置:
'basecontroller' => $basedir . '/src/basecontroller.php'
若你还不懂,去看看autoload_classmap.php吧。
file方式
有了上面这些加载方式还不够么? 是的,还会有一些供全局使用的比如帮助等这样函数,那么好吧,我们就讲这些文件直接包含进来好了。
{ "autoload": { "files": ["src/mylibrary/functions.php"] }}
composer安装扩展后会将其放到
vendor/composer/autoload_files.php
到此刻,世界清静了,composer可以加载我大php世界的各种库,只要你想,就可以自动加载。
以上就是你不知道的composer加载方式的详细内容。
