每当插件创建时new MyClass();
,都应将其分配给唯一命名的变量。这样,就可以访问该类的实例。
因此,如果他在做$myclass = new MyClass();
,那么您可以这样做:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
这是可行的,因为插件包含在全局名称空间中,因此插件主体中的隐式变量声明是全局变量。
如果插件没有在某个地方保存新类的标识符,那么从技术上讲,那是一个错误。面向对象编程的一般原则之一是,某些地方未被某些变量引用的对象将受到清除或清除。
现在,特别是PHP不会像Java那样执行此操作,因为PHP有点像是一个半精打采的OOP实现。实例变量只是其中包含唯一对象名称的字符串。它们之所以起作用,仅是因为变量功能名与->
操作员的交互方式。因此new class()
,愚蠢地做某件事确实可以完美地工作。:)
因此,最重要的是,永远不要做new class();
。这样做$var = new class();
,并做出是$ var在某种程度上对其他位引用它访问。
编辑:几年后
我已经看到很多插件在做的一件事是使用类似于“ Singleton”模式的东西。他们创建一个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
动作挂钩相关的内容中,它将撤消原始插件所挂钩的动作。