如何防止 PHP 命名空间冲突(预捆绑包)

How to prevent PHP namespace conflicts (pre-bundled packages)

假设我们有一个 PHP 项目,其依赖项 AB 每个都依赖于 PHP 库X,但版本不同。

通常,人们会使用 PHP 依赖管理器,例如 composer,它可以通过在兼容 的版本中包含 X 来解决此冲突]AB 或如果无法解决冲突则显示错误。

现在,许多 PHP 应用程序允许用户通过上传预先捆绑的包并将它们解压缩到特定的插件目录来安装插件。

如果 AB 是这样的预捆绑插件,两者都会带来自己的库版本 X ,我们可能 运行 遇到问题,因为没有依赖管理器可用于 select 兼容的 X 或显示错误以防出现none.

为了防止由于 PHP 无法将库 X 以不同版本加载到同一名称空间中而导致的任何此类冲突,我们可以将 AXBX到不同的命名空间(这可能很难自动完成,因为我们需要一个 PHP 解析器...)。

我的问题是:

不改代码没有解决办法。如果文件系统中存在“\Vendor\AnyClass”的两个版本,并且执行代码以同时使用它们,则会出现错误,因为不允许重新声明 class,或者因为预期的 class 不兼容。它只有在 class 的接口实现相同时才有效,即两个代码兼容。如果兼容性问题不仅是那个 class,而是一整棵对象树,即使它们提供了兼容的接口,也可能会对混合来自不同版本的 class 产生不良反应。

更改命名空间就是更改代码。谁对此负责?我可以想到一些能够为每个插件添加特定名称空间前缀的自动代码解析器,但据我所知 PHP 中还没有完成该任务。我公司Java的人说有这样的问题在那里已经解决了,但是我没有详细信息。

此外,它使您的代码库翻倍,并且重复的代码必须仅共享您拥有的一个操作码缓存。

我知道 Wordpress 的核心开发人员仍在为这个问题苦苦挣扎。有一些关于如何使用 Composer 进行依赖管理(即插件及其依赖项)的编码建议,但我认为他们目前没有取得足够的进展。

基本上你有两个选择:1. 创建一个代码命名空间前缀,解析属于插件的所有文件(因此插件作者必须以某种方式包含他的依赖项),更改代码,忍受代码重复,看看在调试时等待您的是什么。缺点是该插件之外的任何代码都无法直接使用插件代码,因为这意味着知道创建的前缀。 2. 实施某种形式的依赖管理,最好使用 Composer,并且不要更改命名空间。

更新: 我又咨询了我的 Java 同事,他们对 Java 的说法基本上和我对 [=30] 的说法是一样的=]:您不能在同一个 class 名称下有两个不同版本的 class,即使 Java 也没有 "magic",但重命名 class到不同的命名空间。