我在我的网站上安装了自定义主题和 SMTP 插件,它们都包含用于不同目的的 Google API PHP 客户端。不幸的是,插件和主题使用的依赖是不同版本的,并且无法轻松升级或降级。
这会导致冲突,插件从主题加载包而不是自己的包,并抛出错误。
这是主题的 Composer。
{
"require": {
"google/apiclient": "^2.2.1"
},
"scripts": {
"pre-autoload-dump": "Google\\Task\\Composer::cleanup"
},
"autoload": {
"psr-4": {
"BH\\": "includes/"
}
},
"extra": {
"google/apiclient-services": [
"Sheets"
]
}
}
主题使用命名空间BH
有没有办法限制使用 Composer 仅为主题(具有命名空间 BH
)执行的代码加载 Google API PHP 客户端文件,而不是使用不同的插件命名空间(例如 ABC
)。
请注意:我尝试过范围界定,但这使整个情况变得更加复杂。
最佳答案
Is there a way to limit using Composer to load the Google API PHP Client files only for the code executed by the theme (with namespace
BH
) and not to the plugin that makes use of a different namespace (sayABC
).
简而言之,不,Composer 中不存在这样的选项。 Composer 根据项目配置(composer.json
以及 vendor/*/composer.json
下面的所有配置)转储自动加载器。
剩下的就是 PHP 中自动加载的工作原理:您使用一个类(或 Interface/Trait/Enum 等),如果尚未加载,则会咨询自动加载器以将类名解析为类定义,通常是一个文件在磁盘上。然后该文件由 PHP 加载并解析(require
等)。
所以这里没有太多魔力。您还可以看到,这取决于命名空间“加载”内容的执行顺序。顺便说一句,(默认)自动加载器。看不到(没有进一步的内省(introspection),由于效率原因没有进行)哪个命名空间实际上需要什么。
如果您想检查详细信息 - 特别是当您已经研究过范围界定时 - Composer 可以在运行时级别提供一些东西。
默认情况下,composer 自动加载器带有前缀。这意味着它将自己添加到自动加载器队列的顶部。在 PHP 中,您可以有多个自动加载器实现。您可以在项目中配置 Composer,使其不将自身添加到队列顶部,而是添加到末尾。
这允许您在前面添加自己的自动加载器,例如,您可以使用它来诊断加载。它还允许您加载不同的内容,但只能加载具有相同类名的内容。
这就是为什么 fork 和重写命名空间(又名“作用域”)通常效果更好,因为类名不同 - 冲突就消失了。
I have attempted scoping and it makes the entire situation even more complex.
是的,但是请记住,归根结底,这是一个依赖冲突。不从根本上解决问题只会迫使你继续采取变通办法。这类冲突在解决之前不会轻易消失。
是的,依赖管理很困难。我们已经说过编程很困难,但是当您遇到第一个依赖冲突时,还有另一个教训需要通过艰难的方式学习。这些不会神奇地消失,并且需要维护(我并不是指那些可以通过提升需求或类似方式轻松解决的依赖项冲突,而是指您依赖的那些依赖项,然后它们就会破坏)。
关于php - 插件和主题之间的依赖冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73251609/