如何防止PHP名称空间冲突(预打包的软件包) [英] How to prevent PHP namespace conflicts (pre-bundled packages)

查看:132
本文介绍了如何防止PHP名称空间冲突(预打包的软件包)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们假设我们有一个PHP项目,依赖项 A B 分别取决于PHP库 X ,但版本不同. /p>

通常,人们将使用PHP依赖管理器(例如composer),通过在兼容 A B的版本中包含 X 来解决此冲突. ,或者如果无法解决冲突,则显示错误.

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

如果 A B 是预先捆绑的插件,并且两者都带来了自己的版本的库 X ,我们可能会遇到问题由于没有依赖项管理器可为我们选择兼容的 X 或在没有依赖项的情况下显示错误.

为防止由于PHP无法将库 X 用不同版本两次加载到同一名称空间而引起的任何此类冲突,我们可以将 A X B X 放入不同的命名空间(这可能很难自动完成,因为我们需要为此使用PHP解析器...)

我的问题是:

  • 您将如何解决此问题?您可以推荐这种方法还是有更好的解决方案?

解决方案

没有更改代码就没有解决方案.如果文件系统中确实存在两个版本的"\ Vendor \ AnyClass",并且执行了代码以使用这两个版本,则会出现错误,因为不允许重新声明该类,或者由于预期的类不兼容.仅当类的接口实现相同(即两个代码兼容)时,它才有效.如果不只是一个类,而是一整个对象树,即使提供了兼容的接口,它们也可能对混合来自不同版本的类做出不良反应,所以兼容性问题变得很复杂.

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

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

我知道Wordpress的核心开发人员仍在努力解决这个问题.关于如何使用Composer进行依赖项管理(即插件及其依赖项),存在一些编码建议,但是我认为它们暂时没有取得足够的进展.

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

更新:我再次咨询了我的Java同事,他们基本上做出了关于PHP的关于Java的相同声明:同一类名下不能有两个不同版本的类,即使Java也没有魔术",而是将类重命名为其他名称空间.

Let's assume we have a PHP project with dependencies A and B each depending on PHP library X, but in a different version.

Usually, one would use a PHP dependency manager such as composer which would either resolve this conflict by including X in a version compatible to both A and B or display an error if the conflict cannot be resolved.

Now, many PHP applications allow their users to install plugins simply by uploading pre-bundled packages and extracting them to a specific plugin directory.

If A and B were such pre-bundled plugins and both would bring their own version of library X, we might run into problems since no dependency manager is available to select a compatible X for us or display an error in case there is none.

To prevent any such conflicts caused by the inability of PHP to have library X being loaded twice with different version into the same namespace, we could put A's X and B's X into different namespaces (which might be hard to do automatically as we would need a PHP parser for that...).

My question is:

  • How would you solve this problem? Can you recommend this approach or is there a better solution?

解决方案

There is no solution without changing the code. If two versions of ´\Vendor\AnyClass´ do exist in the filesystem, and code is executed to use them both, either an error appears because redeclaring that class is not allowed, or because the expected class is incompatible. It will only work if the interface of the class is implemented the same, i.e. the two codes are compatible. The problem of compatibility is complicated if it isn't only that one class, but an entire tree of objects that may react badly to mixing classes from different versions, even though they offer a compatible interface.

Changing the namespace is changing the code. Who's responsible for that? I can think of some automatic code parser that would be able to add a specific namespace prefix for each plugin, but that task hasn't been done to my knowledge in PHP. The Java guys in my company made some remarks that such a problem has been solved there, but I have no details.

Also, it doubles your code base, and the duplicated code has to share only the one opcode cache you have.

I know that the core developers of Wordpress are still struggling with this problem. There are some coded suggestions of how to use Composer for dependency management (i.e. plugins and their dependencies), but I don't think they made enough progress for now.

Essentially you have two choices: 1. Create a code namespace prefixer, parse all the files belonging to a plugin (so the plugin author has to include his dependencies somehow), change the code, live with the code duplication, and see what awaits you when it comes to debugging. The downside is that no code outside of that plugin will be easily able to use the plugin code directly because that would mean to know the created prefix. 2. Implement some form of dependency management, preferably using Composer, and don't change the namespaces.

Update: I consulted my Java co-workers again, and they basically made the same statement about Java that I made about PHP: You cannot have two different versions of a class under the same class name, and there is no "magic" even for Java but renaming the class to a different namespace.

这篇关于如何防止PHP名称空间冲突(预打包的软件包)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆