Replace “怎么说?”;替换“;与作曲家合作?

Replace “怎么说?”;替换“;与作曲家合作?,replace,composer-php,package-managers,Replace,Composer Php,Package Managers,那么,“”属性是如何使用的呢?我读过作曲家的文件,但仍然不明白。搜索更多信息还没有回答我的问题 当我在github上查看composer.json文件时。我看不出替换将如何工作。有人能给我解释一下这是怎么回事吗?以及变量“self.version”将等于什么?Composer文档给出了两个基本示例。我会尽力解释: 列出由此程序包替换的程序包。这允许您分叉一个包,以不同的名称发布它,并提供它自己的版本号,而需要原始包的包继续使用您的分叉,因为它替换了原始包 假设您的软件使用original/lib

那么,“”属性是如何使用的呢?我读过作曲家的文件,但仍然不明白。搜索更多信息还没有回答我的问题


当我在github上查看composer.json文件时。我看不出替换将如何工作。有人能给我解释一下这是怎么回事吗?以及变量“self.version”将等于什么?

Composer文档给出了两个基本示例。我会尽力解释:

列出由此程序包替换的程序包。这允许您分叉一个包,以不同的名称发布它,并提供它自己的版本号,而需要原始包的包继续使用您的分叉,因为它替换了原始包

假设您的软件使用
original/library
other/package
,这本身也需要
original/library

现在您认为
original/library
需要集成一个特性,但是维护人员不会让您的建议出现在他们的包中。您决定将该库命名为
better/library
,并标记一个新版本

回到你的软件。当然,它应该开始使用
better/library
,因此您需要它,但是
other/package
仍然需要
原始/库
-代码复制!您如何让另一个包使用您的
更好的/library
,而不使用fork,只更改composer.json(您仍然与
原始/library
兼容,因此它应该可以工作)

将替换键添加到
composer.json

"replace": {
    "original/library":"1.0.2"
}
现在,Composer知道,在解决
其他/package
的依赖关系时,来自
更好的/library
的任何包都与
原始/library
的包一样好

这对于包含子包的包也很有用,例如,主symfony/symfony包包含所有symfony组件,这些组件也可以作为单独的包提供。如果您需要主软件包,它将自动满足其中一个单独组件的任何要求,因为它将替换它们

同样的规则,一个稍微不同的角度:对于任何其他需要一些特性的组件,需要框架的组件是一个很好的方法。但是,如果您需要软件中的完整框架,以及另一个库,该库随后也需要该框架的组件,那么框架的
replace
声明允许Composer不必安装该单个组件两次,因为它已经包含在完整框架中

注意:替换版本中的占位符通常不好

在我最初的回答中,我建议:

"replace": {
    "original/library":"1.*"
}
这会产生后果:Composer现在会将您的库版本1.0.0视为与原始库的任何1.x版本一样好,即使他们在某一天修复内容或添加功能并发布版本1.2.34。这也意味着,如果您的
其他/package
某天得到更新,并且需要
原始/library:^1.1
,则库中的替换仍处于活动状态,并声明它可以替换任何版本
1.*
,即使您不更新其中的任何内容,也可以,如果您不做一些工作,您的旧代码将永远无法实现原始库的新功能,但替换代码恰恰说明了这一点


所以本质上:在替换版本中避免通配符版本!如果你使用它们,你会对未来做出你无法知道或预测的陈述(除非你能控制
原创/库
,但即使如此,也要非常小心)。始终使用您知道并可以完全重新实现的
原始/库的特定版本。

当您创建自己的软件包时,您可以在
composer.json中定义它是什么类型的软件包,它基本上告诉composer您的软件包已经安装,因此无需再次安装

如果您使用,它会告诉Composer您的包想要用您自己的fork替换原始包,所以其他包不需要安装它

例如,如果
a/a
软件包需要
b/b
,并且您要求替换
b/b
,则它不会在Composer
安装上下载

此处将对此进行更详细的解释:


我想我差不多拿到了。所以我不明白的是,composer如何知道替换什么(包a和b或包c和d),但是composer查看类名来比较它,对吗?因此,任何名为a/b的包都将被x/b或y/b替换。添加self.version可能意味着只有在版本号相等时才进行替换。Composer只检查各自
Composer.json
文件中的包名。它不检查类名。为了让技巧完全发挥作用,您必须在包中提供替换另一个包的兼容性(案例1)。Composer仍然会将您的
better/library
替换为
original/library
,但如果原始版本中使用的类在better版本中没有工作等价物,代码将失败。我遇到了另一种情况(类似于关于子包的第二个示例),这是为了避免在您知道不需要的情况下需要一些多边形填充:“如果您的项目不需要一些Symfony多边形填充,请使用composer.json的replace部分。这将消除这些多边形填充的任何开销,因为它们不再是您项目的一部分。”@Sven,如果
原件/库
更好的/library
都用
*
替换,会怎么样?我能强迫它使用其中一个吗?@Pini:循环依赖总是一个非常糟糕的主意,我无法想象这样一个场景有什么有用的用例。