プラグインがを作成するたびnew MyClass();
に、一意の名前の変数に割り当てる必要があります。これにより、クラスのインスタンスにアクセスできます。
彼がやっていたの$myclass = new MyClass();
であれば、あなたはこれを行うことができます:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
これは、プラグインがグローバルネームスペースに含まれているため機能します。そのため、プラグインのメインボディの暗黙的な変数宣言はグローバル変数です。
プラグインが新しいクラスの識別子をどこかに保存しない場合、技術的にはそれはバグです。オブジェクト指向プログラミングの一般原則の1つは、どこかの変数によって参照されていないオブジェクトは、クリーンアップまたは削除の対象になるということです。
現在、特にPHPはJavaのようにこれを行いません。これは、PHPが半種のOOP実装であるためです。インスタンス変数は、固有のオブジェクト名を含む単なる文字列です。変数関数名の相互作用が->
演算子と連動する方法のためにのみ機能します。だから、ただやるnew class()
だけで、ばかげて完璧に機能します。:)
結局のところ、絶対にしないでくださいnew class();
。やる$var = new class();
とそれを参照するために、他のビットのために何らかの方法でそれの$ varがアクセスできるようにします。
編集:数年後
多くのプラグインが行っていることの1つは、「シングルトン」パターンに似たものを使用することです。クラスの単一インスタンスを取得するgetInstance()メソッドを作成します。これはおそらく私が見た中で最高のソリューションです。プラグインの例:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
getInstance()が初めて呼び出されると、クラスがインスタンス化され、ポインターが保存されます。これを使用して、アクションをフックできます。
この問題の1つは、そのようなものを使用する場合、コンストラクター内でgetInstance()を使用できないことです。これは、新しいインスタンスが$ instanceを設定する前にコンストラクターを呼び出すため、コンストラクターからgetInstance()を呼び出すと無限ループが発生し、すべてが中断されるためです。
回避策の1つは、コンストラクターを使用しない(または、少なくともその中でgetInstance()を使用しない)ことですが、アクションなどを設定するためにクラスに明示的に「init」関数を使用することです。このような:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
このような場合、ファイルの最後で、クラスがすべて定義された後など、プラグインのインスタンス化は次のように簡単になります。
ExamplePlugin::init();
Initはアクションの追加を開始し、その際にgetInstance()を呼び出します。これにより、クラスがインスタンス化され、そのうちの1つのみが存在することが確認されます。init関数がない場合、代わりに最初にクラスをインスタンス化するためにこれを行います:
ExamplePlugin::getInstance();
元の質問に対処するために、外部(別のプラグインでも)からそのアクションフックを削除するには、次のようにします。
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
plugins_loaded
それをアクションフックにフックされたものに入れると、元のプラグインにフックされているアクションが取り消されます。