Php WordPress类名冲突

Php WordPress类名冲突,php,wordpress,class,conflict,Php,Wordpress,Class,Conflict,我已经创建WordPress插件几个月了,我已经开发了一组“基类”(大多数是抽象类,但不是全部),我使用这些插件(一些用于所有插件,另一些用于插件需要类提供的特定内容时-可能是管理屏幕或可视化编辑器上的按钮或其他) 当然,这非常有效,但是如果我更新一个或多个基类以添加一些新功能,那么如果有人安装了我的多个插件,那么这些插件中的一个或多个很可能崩溃 这是因为,如果使用更新类的旧版本的插件更早加载,那么它将“保留”该名称,而其他需要更新类的插件则没有功能/fix/etc 我尝试过“好”的解决方案,但

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

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

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

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

名称空间显然可以工作,但无法使用,因为许多流行的托管公司都在使用5.2x版本的PHP(这可能是WordPress也不需要5.3版本的原因)

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

类childClassName扩展了$parentClassName

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

我也不能强迫每个人每次都升级他们所有的插件,因为它可能会在他们可以升级之前崩溃,我不确定这对我来说是否合理,我要求他们中的任何一个,甚至我可以亲自更新和重新测试,每一次,现在的几乎10个插件中的每一个,将来都会有更多的插件

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

是否有一些PHP代码可以让我实现一个简单、简单的解决方案来解决这个常见的类名冲突问题

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

看起来没有人知道如何在PHP中实现这一点,也许这是不可能的,所以我采用了上面提到的方法

我想我会把它放在这里,因为这是我最终得到的效果很好的东西,如果不是我所希望的,也许它可以帮助其他人:

  • 我在基类名称中添加了标记,例如:
  • 类someBaseClass[TokenNameGoeSher](我使用了[ReplaceWithVersionNumber])

    类someChildClass扩展someBaseClass[TokenNameGoesher]

  • 我创建了一个名为createNewClass的方法,并将类名(作为字符串)和任何要传递给新类的参数(在数组中)传递给它
  • 我还传递了一些信息,比如应用程序中使用的令牌值(在我的例子中是版本号)和名称空间(如果我可以使用PHP5.3及更高版本,则使用该名称空间来代替令牌值)

    然后我使用反射创建了这个类。虽然反射速度明显较慢,但我发现我在需要使用createNewClass时没有那么多次,所以在方便记忆和提高清晰度之间取得了平衡

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

    其中$desiredClassName是根据类名和其他参数构建的:在我的例子中是version和namespace

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

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

  • 当我为一个新的应用程序复制类库时,我只是做了大量的搜索,并在所有文件中用我想要替换的标记替换它。如果我不必像WordPress插件那样担心与类库的其他版本发生冲突,它可能是版本号,甚至是空字符串
  • 这很容易做到,而且效果很好,尽管返回并插入代币是一件乏味的事情

    当然,这一切都可以用标记来完成,但我不想记住在名称上加后缀,以及我使用的标记名称等等


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

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

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

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

    希望有帮助!

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

    若php能够提供卸载/加载类的方法,那个么这个问题就可以很容易地解决。但同样,你们需要重新链接/实例化你们的其他依赖的活动插件,以便使用新类的对象,这涉及到现有插件的停用和激活

    同样的想法,我可以想到这个解决方案,你很清楚你有1,2,3..n个插件使用X类。1和2个插件正在使用旧版本的X,你将要用新版本的X安装/更新插件3。停用所有插件并首先激活插件(3)具有最新功能/版本的class 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);
    }
    
    $all_plugins=array(
    ABSPATH.'wp-content/plugins/plugin_1/index.php',
    ABSPATH.'wp-content/plugins/plugin_2/index.php'
    ......
    ABSP-wp-c