假设我将代码库作为独立的 PHP 类发布。然后有人在他们的应用程序中使用该库的 1.0 版。后来,我发布了该库的 2.0 版,而同一个人出于任何原因需要在其应用程序中同时使用 1.0 和 2.0,因为他或我破坏了与新版本的向后兼容性。
如果类名不同,则很容易包含和实例化两者,因为没有命名冲突。但是如果类名保持不变,我们就会遇到问题:
include /lib/api-1.0/library.php;
$oldlibary = new Library();
include /lib/api-2.0/library.php;
$newlibrary = new Library();
这是行不通的,因为我们不能同时加载两个名称为 name 的类Library
。另一位开发人员建议的另一种选择是使用命名空间。以下应该有效:
namespace old {
include /lib/api-1.0/library.php;
}
namespace new {
include /lib/api-2.0/library.php;
}
$oldlibary = new old\Library();
$newlibrary = new new\Library();
不幸的是,这不是非常可扩展的。它适用于 2 实例情况(希望我不必首先使用),但要将其扩展到 3、4、5 或更多实例,您需要定义额外的命名空间并设置,如果你一开始就没有使用这些命名空间,那是一堆不必要的代码。
那么有没有办法动态地创建一个命名空间,包含一个文件,并在一个唯一命名的变量中实例化该文件中包含的类?
让我补充一些澄清......
我正在构建一组库,供为几个 CMS 平台构建插件/模块的其他开发人员使用。理想情况下,每个人都将始终使用我的库的最新版本,但我不能保证,我也不能保证最终用户在新版本可用时总是升级他们的模块。
我正在尝试使用的用例是最终用户安装两个不同开发人员的两个不同模块:称它们为Apple和Orange。这两个模块都使用我的库的 1.0 版,这很棒。我们可以将它实例化一次,两组代码都可以从该功能中受益。
后来,我为这个库发布了一个小补丁。它的版本为 1.1,因为它不会破坏与 1.x 分支的向后兼容性。Apple的开发人员立即更新了他的本地版本并推送了他的系统的新版本。Orange的开发者正在度假,不打扰。
当最终用户更新Apple时,她会获得我的库的最新维护版本。因为它是一个维护版本,所以完全替换 1.0 版被认为是安全的。因此,代码仅实例化了 1.1,而Orange从维护补丁中受益,即使开发人员从未费心更新他们的版本。
甚至后来,出于某种原因,我决定更新我的 API 以向 Facebook 添加一些钩子。新功能和 API 扩展对库有很大的改变,因此我将版本升级到 2.0 以将其标记为在所有情况下都可能不向后兼容。苹果再次介入并更新了他的代码。/lib
没有任何问题,他只是用最新版本 替换了他文件夹中的我的库。Orange决定回到学校成为一名小丑,并且已经停止维护他的模块,因此它没有得到任何更新。
当最终用户使用新版本更新Apple时,她会自动获得我的库的 2.0 版。但是Orange在他的系统中有代码已经添加了 Facebook 钩子,所以如果 2.0 默认滚入他的库,就会发生冲突。因此,我没有完全替换它,而是为Apple实例化 2.0 一次,然后并排实例化Orange附带的 1.0 版本,以便它可以使用正确的代码。
这个项目的全部目的是允许第三方开发人员基于我的代码构建系统,而不依赖于它们是否可靠,并在他们应该更新他们的代码时。对于最终用户来说,什么都不会中断,并且在其他人的系统中使用时更新我的库应该是一个简单的文件替换,而不是遍历和更改所有类引用。