鉴于 Composer 可以在composer.json
文件的provide
部分中使用虚拟包,如果没有人负责,如何管理这些虚拟包的版本?
我的意思是,如果任何人都可以创建"邪恶">包,说明它是provide
-s特定的虚拟包(任何地方都没有存储库),那么他们可以指定他们喜欢的任何版本。这可能会与其他"好">包发生冲突,对吧?
根据我的经验,这个"虚拟包"功能尚未被广泛使用,并且由于目前的实现方式,它肯定有其缺点。
如果你在 Packagist 上查看这个搜索结果,你会看到三个顶级包是psr/log
(真正的接口包)、psr/log
(另外两个真实包使用的虚拟包,但方式错误)和psr/log-implementation
(被很多包使用,包括monolog/monolog
)。
这个例子说明了人们会误解这个功能并做错事。您不能提供psr/log
因为这是一个具有实际接口定义的真实包。要求psr/log
同时提供它就更没有意义了。
您还正确地发现,没有中央实体来决定虚拟软件包的哪些版本应该存在,更不用说应该存在哪些虚拟软件包名称了。这不是什么大问题,因为决定真实包的名称是相同的:一个开发人员想到一个名称,仅此而已。此过程不太可能产生非自愿冲突,因为通常 Github 帐户名称用作供应商名称,而 Github 已经使它们唯一。正如Jordi在他的博客中指出的那样,恶意冲突在现实世界中并不存在,因为Composer用来命名包的一般结构。
回到虚拟包功能:有两篇博客文章在讨论它。
第一个通过上面提到的虚拟psr/log-implementation
包的示例解释了使用此功能。我不会在这里复制类似教程的文本。
第二个(在第一个末尾链接和回复)讨论了虚拟包的整个方法的缺点。
一些要点:
1)严格来说(就像代码编译一样),库本身的代码不需要提供
psr/log-implementation
的包。它只需要LoggerInterface
(恰好在psr/log
包中)。4)
psr/log-implementation
,或任何虚拟包,作为一个包是非常有问题的。此虚拟包没有定义。[...]5)有一天,有人可能会决定引入另一个虚拟软件包,称为
the-real-psr/log-implementation
(他们可以很容易地做到这一点,对吧?此类软件包可以与现有的psr/log-implementation
软件包完全交换,但为了有用,每个现有的符合PSR-3标准的记录器软件包也需要在其提供部分中提及该虚拟软件包。[...]
由于好的软件包存在所有这些问题和不确定性,因此它们并不真正使用此功能也就不足为奇了。
但是,您不能像在问题中概述的那样滥用它来做坏事。是的,任何包都可以声明它提供任何其他包。但就像psr/log
一样,有一个包声明它提供了另一个包不会神奇地让每个人都下载该包。它的工作方式是一个包声明它提供了另一个包,通过要求这个包,虚拟包也会被包含,并将满足其他包对虚拟包的任何依赖关系。
但是不要求包提供东西会把所有内容都排除在外。
为了包含不良软件,必须有人require
它。这最好作为看起来无辜的库的间接依赖来完成,并且需要毫无戒心的开发人员的帮助,该开发人员在没有正确审查的情况下主动提取此代码。
这可能是我所有事情的中心点:如果你将某人的代码拉入你自己的项目中,确保你通过审查它来理解该代码的作用(这不仅是关于恶意的东西,还有基本的代码质量,因为有一天你可能会被迫调试一个问题),或者确保你可以足够信任那个来源,不会对你做坏事。但是,您自己的代码库不受您不需要的包的影响(具有这种效果的最后一个错误是处理replace
信息,但我现在没有发现这个问题)。