composer基础与实践-下篇

在composer中,psr-0,psr-4是两个比较类似的”自动加载”规范,前者已经不建议使用,后者是前者的优化版本,是当下主流选择。

composer基础与实践-中篇中,使用classmap将某目录下所有class自动加载,使用files将指定文件一次性引入。那么psr-0和psr-4又做了什么呢?

我感受最大的区别,就是psr-0和psr-4定义了命名空间和多级目录之间的映射规则,从而可以很方便的组织一个目录层次较深,命名空间较多的项目,而classmap和files仅仅解决了单一文件或者单一目录的自动加载问题。

1,先看psr-0,编写composer.json如下:

我期望common\util命名空间的类,都去common/util目录下查找,所以如上定义。然而psr-0之所以被淘汰的重要原因,就是它奇葩的设定。

实际上这个配置方式,它先会切换到common/util目录下,然后它会将common\\util命名空间拆分成目录层次common/util,拼接到目录后面形成common/util/common/util,在这个目录下查找对应的类文件,与我想要的效果大相径庭。

我们还是看一下这种情况下的目录分布以及调用代码。

这是根据psr-0规则和我们的composer.json配置,编写的Writer类。

这是入口文件的调用方式,创建了common\util命名空间下的Writer对象,于是命中了psr-0规则,在common/util/common/util目录下找到了对应的Writer.php类。

可以看一下composer的autoload_namespaces.php文件,它记录了生成的psr-0映射规则。

虽然映射到了common/util目录,但是在实际加载的时候又把namespace部分追加到目录后面,导致目录嵌套重复。

2,psr-0不仅存在上述问题,还有其他一些小区别(不是重点)。psr-4则解决了psr-0存在的一些问题,更加好用了。

把上面的composer.json配置的psr-0改成psr-4,其他不变。

psr-4的行为更加符合预期,它在遇到common\util命名空间的类时,会去common/util目录下直接查找类文件,而不是去common/util/common/util下。

效果符合预期。之前提到psr规范支持多级目录的加载,只要目录层次和命名空间一致即可。那么创建一个common/util/impl/Meta.php,命名空间根据目录结构定义为common\util\impl,并在Writer中调用它,看composer是否可以自动加载到Meta.php。

可见,因为我们配置了psr-4加载common\util命名空间的原因,所以common\util\impl命名空间作为其子命名空间会依据目录结构自动加载。

因为Psr-0已淘汰,如果自己写项目建议忘掉psr-0直接使用psr-4即可。另外,composer在yii2.0等框架中被广泛使用,掌握其原理对管理该类项目有很大的好处,建议掌握上述内容。

发表评论

电子邮件地址不会被公开。