我在我的网站上安装了一个自定义主题和一个SMTP插件,它们都包括用于不同用途的Google API PHP客户端。不幸的是,插件和主题使用的依赖关系版本不同,无法轻松升级或降级。
这导致了一个冲突,即插件从主题而不是自己的主题加载包,并引发错误。
这是这个主题的作曲家。
{
"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加载Google API PHP客户端文件仅用于主题执行的代码(使用名称空间BH
(,而不用于使用不同名称空间的插件(例如ABC
(。
请注意:我已经尝试了范围界定,这使得整个情况更加复杂。
是否有办法限制使用Composer仅为主题(使用名称空间
BH
(执行的代码加载Google API PHP客户端文件,而不加载使用不同名称空间(例如ABC
(的插件。
简而言之,不,Composer中不存在这样的选项。Composer根据项目配置(composer.json
和vendor/*/composer.json
以下的所有配置(转储自动加载器。
剩下的就是PHP中的自动加载工作原理:您使用一个类(或Interface/Trait/Enum等(,如果尚未加载,则会咨询自动加载程序,将类名解析为类定义,通常是磁盘上的文件。然后,该文件由PHP(require
等(加载并解析
所以这里没有太多魔法。您还可以看到,这取决于哪个命名空间"的执行顺序;负载";什么(默认(自动加载器btw.看不到(由于效率原因没有进行进一步的内省(哪个命名空间实际需要什么。
如果你想检查细节——尤其是在你已经研究了范围界定的时候——Composer在运行时级别上可以提供一些东西。
默认情况下,composers autoloader的前缀为。这意味着它将自己添加到自动加载器队列的顶部。在PHP中,可以有多个自动加载器实现。您可以在项目中配置Composer,使其不将自己添加到队列的顶部,而是添加到末尾。
这允许您在前面添加自己的自动加载器,例如,您可以使用它来诊断加载。它还允许您加载不同的东西,但只能加载每个具有相同类名的东西。
这就是为什么分叉和重写名称空间(也称为"作用域"(通常效果更好,因为类名不同,冲突就消失了。
我尝试了范围界定,这使整个情况变得更加复杂。
是的,但请记住,归根结底,这是一个依赖冲突。不从根本上解决它只会迫使你保持变通办法。这种冲突在解决之前不会轻易消失。
是的,依赖性管理很难。我们已经说过编程很难,但当你遇到第一次依赖冲突时,还有另一个教训需要从中吸取。这些不会神奇地消失,它们需要维护(我不是指那些通过提升需求或类似的方式很容易解决的依赖关系冲突,而是指那些你依赖的依赖关系,然后它们就会破裂(。