2013-06-23 128 views
1

我已经创建了几个月的WordPress插件,并且我开发了一组“基类”(大部分是抽象类,但不是全部),我使用插件(有些与所有插件一起使用,其他插件在插件需要该类提供的特定内容时使用 - 可能是管理屏幕或可视编辑器上的按钮或其他内容)。WordPress类名称冲突

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

这是因为如果插件使用旧版本的更新类加载得更早,那么它会“保留”该名称,而其他需要更新类的插件不具有该功能/修正/等。

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

命名空间显然工作,但因为有很多流行的托管公司使用的是5.2X版本的PHP(也许就是为什么WordPress的不需要或者5.3)

我试图动态创建的类名和无法使用使用类工厂,但他们没有工作,或没有克服重新命名所有基类的需要。我甚至尝试(虽然我没想到它的工作,但你永远不知道用PHP):

类childClassName扩展$ parentClassName

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

我也不能强迫每个人每次都升级所有的插件,因为它可能会在可能之前崩溃,而且我不确定这是否合理,因为我需要它们,甚至我可以亲自更新和每次重新测试时,现在几乎有10个插件会在未来更多。

我最好的解决方案是使用工厂创建所有基类,并将标记放入我的基类中,以便我可以执行全局搜索并进行替换,以便每个插件的类名都是唯一的;注意单独的可替换的令牌将起作用。

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

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

一点也没有看起来像任何人都知道如何在PHP中做到这一点,也许它不能完成,所以我采用了我上面提到的方式。

我想我应该把它放在这里,因为这是我结束了行之有效,如果不是我所希望的,也许这可以帮助别人:

  1. 我加入令牌基地类名称,例如:

类someBaseClass [TokenNameGoesHere](I使用的ReplaceWithVersionNumber])

类someChildClass延伸someBaseClass [TokenNameGoesHere]

  1. 我创建了一个名为createNewClass方法和传递的类名(作为一个字符串),并传递给新类(在阵列)的任何参数。

我也通过在应用程序中(版本号在我的情况下)被使用,如令牌值信息和所述命名空间(被用于代替令牌值如果我可以使用PHP 5.3以上)。

然后我用反射来创建类。尽管反射速度明显较慢,但我发现当我需要使用createNewClass时,我没有那么多次,所以记忆的容易性和增加的清晰度都被赢了。

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

其中$ desiredClassName是从类名和其他参数构建而成的:version和namespace。

然后,到处我想创造一个基类对象我会使用:

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

  1. 当我复制类库到一个新的应用程序时,我只是做了大量的搜索,并替换了我想在所有文件中替换它的令牌。如果我不必担心与我的类库的其他版本发生冲突(比如我使用WordPress插件),它可能是版本号,甚至是空字符串。

这很容易做到,而且效果很好,虽然回去并插入令牌非常繁琐。

这一切都可以,当然,可以用做只是令牌,但我不想记得要不要穿上名称后缀和令牌我用的名字和诸如此类的东西。

我希望帮助别人,如果任何人有一个更好的方法(这对我来说意味着更少的代码修改和更清晰的代码),我很想听到它。

+0

正确的类前缀对我来说都是最有效的工作 –

+0

不确定你在这种情况下的含义。 我有一组类像:myUniquePrefix_ClassName1,myUniquePrefix_ClassName2,myUniquePrefix_ClassName3等 他们是一些插件的一部分。 我更新这些类(相同的类名只是其中的新东西),更新是其他插件的一部分。 如果同时安装了较旧和较新的版本,则WordPress可能首先加载较旧的类,而较新的类不会加载(因为名称相同),并且依赖更新类的插件失败。 请澄清你的意思,谢谢。 –

+0

不要在插件之间共享类名称。保持独特。 –

回答

0

不知道你是否找到了适合你的问题的解决方案。我处理同样的问题,我的做法(不完美,但我需要什么)将是这样一个:

从变量创建可重用的类中的一个别名,像这样:

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

希望它有帮助!

0

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

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

用同样的想法我可以想到这个解决方案,你非常清楚你有1,2,3 ..n插件使用X类。 1个& 2插件使用较旧版本 X和您要安装/更新插件3 版本X的停用所有你的插件&首先激活插件(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); 
} 

* &您不要修改的类X的现有功能签名提供如果好禁用/激活你的插件,你虽然可以增加新的功能。