每当插件创建new MyClass();
, 它应该将其分配给唯一命名的变量。这样,就可以访问该类的实例。
所以如果他在做$myclass = new MyClass();
, 然后你可以这样做:
global $myclass;
remove_action( \'wp_footer\', array( $myclass, \'my_action\' ) );
这是因为插件包含在全局名称空间中,所以插件主体中的隐式变量声明是全局变量。
如果插件没有将新类的标识符保存在某个地方,那么从技术上讲,这就是一个bug。面向对象编程的一般原则之一是,在某个地方没有被某个变量引用的对象将被清除或消除。
现在,PHP尤其不像Java那样做到这一点,因为PHP有点像是一个半死不活的OOP实现。实例变量只是字符串,其中包含唯一的对象名,诸如此类。它们之所以有效,是因为变量函数名交互与->
操作人员所以就这么做new class()
确实可以完美地工作,只是很愚蠢。:)
所以,底线是,永远不要这样做new class();
. 做$var = new class();
并以某种方式使$var可供其他位引用。
编辑:年后
我看到很多插件都在做一件事,那就是使用类似于“单例”模式的东西。它们创建一个getInstance()方法来获取类的单个实例。这可能是我见过的最好的解决方案。插件示例:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
第一次调用getInstance()时,它实例化类并保存其指针。你可以用它来勾引行动。
这样做的一个问题是,如果使用这样的东西,就不能在构造函数中使用getInstance()。这是因为new在设置$instance之前调用构造函数,因此从构造函数调用getInstance()会导致无限循环并中断一切。
一种解决方法是不使用构造函数(或者至少不在其中使用getInstance()),而是在类中显式使用“init”函数来设置操作等。像这样:
public static function init() {
add_action( \'wp_footer\', array( ExamplePlugin::getInstance(), \'my_action\' ) );
}
这样,在文件末尾,在定义完类之后,实例化插件就变得很简单了:
ExamplePlugin::init();
Init开始添加您的操作,并在这样做时调用getInstance(),它实例化该类并确保其中只存在一个。如果没有init函数,则可以这样做来初始化该类:
ExamplePlugin::getInstance();
为了解决最初的问题,可以这样从外部删除该操作挂钩(在另一个插件中也可以这样做):
remove_action( \'wp_footer\', array( ExamplePlugin::getInstance(), \'my_action\' ) );
把它放在钩住的东西里
plugins_loaded
操作挂钩,它将撤消由原始插件挂钩的操作。