WordPress类名冲突

时间:2013-06-23 18:43:08

标签: php wordpress class conflict

我已经创建了WordPress插件几个月了,我已经开发了一组“基类”(大多数是抽象类,但不是全部)我使用插件(有些是使用的)对于所有插件,当插件需要类提供的特定内容时可能会使用其他插件 - 可能是管理屏幕或可视化编辑器上的按钮等等。

当然,这很有效但是如果我更新一个或多个基类来添加一些新功能,那么如果有人安装了多个插件,那么这些插件中的一个或多个插件很可能崩溃。

这是因为如果使用较旧版本的更新类的插件加载较早,则它“保留”该名称,而其他需要更新类的插件则没有功能/修复/等。

我尝试过“很好”的解决方案,但我唯一能够可靠地工作的是改变每个插件的实际基类名称,这远非理想。

命名空间显然有效,但无法使用,因为许多流行的托管公司正在使用5.2x版本的PHP(可能为什么WordPress也不需要5.3)

我尝试动态创建类名并使用类工厂,但它们不起作用或者没有克服重命名所有基类的需要。我甚至尝试过(虽然我没想到它会起作用,但你从来不知道用PHP):

class childClassName扩展$ parentClassName

这种情况不是那么不寻常(人们每次都会从头开始重写所有内容和/或使用不同的类名),但我找不到解决方案,我想不出优雅的问题。它甚至不是WordPress问题,在公司内使用公共基类的多个应用程序也会遇到同样的问题。

我也不能强迫每个人每次都升级他们的所有插件,因为它可能会崩溃,我不确定这对我来说是否合理,甚至是我可以亲自更新和重新安装 - 测试,每次,现在几乎所有10个插件,以及更多的插件。

我目前最好的解决方案是使用工厂来创建所有基类并在我的基类中放置令牌,我可以进行全局搜索和替换,以便每个插件的类名都是唯一的;请注意,可替换的令牌本身就可以使用。

是否有一些PHP代码可以让我为这个常见的类名冲突问题找到一个简单易用的解决方案?

========================================

看起来好像没有人知道如何在PHP中执行此操作,也许它无法完成,所以我按照上面提到的方式进行操作。

我以为我会把它放在这里,因为这就是我最终得到的,如果不是我所希望的,也许它可以帮助别人:

  1. 我在基类名称中添加了标记,例如:
  2. class someBaseClass [ TokenNameGoesHere ](我用[ ReplaceWithVersionNumber ])

    class someChildClass扩展someBaseClass [ TokenNameGoesHere ]

    1. 我创建了一个名为createNewClass的方法,并传递了类名(作为字符串)和任何传递给新类的参数(在数组中)。
    2. 我还传递了应用程序中使用的令牌值(在我的情况下为版本号)和命名空间(如果我可以使用PHP 5.3及更高版本,则用于代替令牌值)等信息。

      然后我用反射创建了这个类。虽然反射明显较慢,但我发现当我需要使用createNewClass时,我没有那么多次,因此易于记忆和提高清晰度的折衷胜出。

      $ reflectionOfClass = new \ ReflectionClass($ desiredClassName); $ newObject = $ reflectionOfClass-> newInstanceArgs($ ParametersToPass);

      其中$ desiredClassName是根据类名和其他参数构建的:在我的情况下是版本和命名空间。

      然后,在我想创建基类对象的任何地方,我都会使用:

      $ myNewObject = $ this-> createNewObject(“someBaseClass”,其他参数);

      1. 当我将类库复制到一个新的应用程序时,我只是进行了大量的搜索,并将令牌替换为我想用所有文件替换它的内容。它可能是版本号甚至是空字符串,如果我不必担心与我的类库的其他版本冲突,就像我使用WordPress插件一样。
      2. 这很容易做到并且效果很好虽然重新开始并插入令牌很乏味。

        当然,这一切都可以只用令牌来完成,但我不想记得在名称和我正在使用的令牌名称上添加后缀等等。

        我希望能帮助某人,如果有人有更好的方法(对我来说意味着更少的代码修改和更多的代码清晰度)我很乐意听到它。

2 个答案:

答案 0 :(得分:0)

不确定您是否找到了正确的问题解决方案。我正在处理同样的问题和我的方法(不完美,但我需要的是)就是这个:

从变量创建可重用类的类别名,如下所示:

$aliasclass = $really_unique_prefix."_Prefix_MyPlugin_Class";
class_alias("Prefix_MyPlugin_Class", $aliasclass);
new $aliasclass();

希望它有所帮助!

答案 1 :(得分:0)

是命名空间是完美的解决方案。

如果php可以提供卸载/加载类的方法问题可以很容易解决。但是,您需要重新链接/实例化其他依赖的活动插件,以便使用新类的对象,这涉及停用和激活现有插件。

同样的想法,我可以想到这个解决方案,你很清楚你有使用X类的1,2,3 .. n插件。 1& 2个插件正在使用旧版版本的X,您即将使用较新版本的X安装/更新插件3.停用所有插件&首先激活插件(3),其中包含您最新的X类功能/版本,然后激活所有其他功能。

$all_plugins = array(
    ABSPATH.'wp-content/plugins/plugin_1/index.php',
    ABSPATH.'wp-content/plugins/plugin_2/index.php'
    ......
    ABSPATH.'wp-content/plugins/plugin_n/index.php'
);
if (class_exists('X') && X::version < currentXVersion) {
    deactivate_plugins($all_plugins);
    $plugin_3_lastest_class_X = ABSPATH.'wp-content/plugins/plugin_3/index.php';
    array_unshift($all_plugins, $plugin_3_lastest_class_X);
    activate_plugins($all_plugins);
}

*提供是否可以停用/激活您的插件&amp;如果不修改X类现有函数的签名,可以添加新函数。