Jedes Mal, wenn ein Plugin ein erstellt new MyClass();
, sollte es einer eindeutig benannten Variablen zugewiesen werden. Auf diese Weise kann auf die Instanz der Klasse zugegriffen werden.
Wenn er es also tun würde $myclass = new MyClass();
, dann könnten Sie dies tun:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Dies funktioniert, weil Plugins im globalen Namespace enthalten sind, sodass implizite Variablendeklarationen im Hauptteil eines Plugins globale Variablen sind.
Wenn das Plugin den Bezeichner der neuen Klasse nicht irgendwo speichert , ist das technisch gesehen ein Fehler. Eines der allgemeinen Prinzipien der objektorientierten Programmierung ist, dass Objekte, auf die von keiner Variablen irgendwo verwiesen wird, bereinigt oder beseitigt werden müssen.
Insbesondere PHP tut dies nicht wie Java, da PHP eine halbherzige OOP-Implementierung ist. Die Instanzvariablen sind nur Strings mit eindeutigen Objektnamen. Sie funktionieren nur aufgrund der Art und Weise, wie die Interaktion mit dem Variablenfunktionsnamen mit dem ->
Operator funktioniert . So einfach zu machen new class()
kann in der Tat perfekt funktionieren, nur dumm. :)
Unterm Strich also niemals new class();
. Machen Sie $var = new class();
das $ var auf irgendeine Weise zugänglich, damit andere Bits darauf verweisen können.
Edit: Jahre später
Eine Sache, die ich bei vielen Plugins gesehen habe, ist die Verwendung eines ähnlichen Musters wie "Singleton". Sie erstellen eine getInstance () -Methode, um die einzelne Instanz der Klasse abzurufen. Dies ist wahrscheinlich die beste Lösung, die ich gesehen habe. Beispiel Plugin:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
Beim ersten Aufruf von getInstance () wird die Klasse instanziiert und der Zeiger gespeichert. Damit können Sie Aktionen einbinden.
Ein Problem dabei ist, dass Sie getInstance () nicht im Konstruktor verwenden können, wenn Sie so etwas verwenden. Dies liegt daran, dass der Konstruktor von new vor dem Festlegen der $ -Instanz aufgerufen wird. Daher führt der Aufruf von getInstance () aus dem Konstruktor zu einer Endlosschleife und unterbricht alles.
Eine Problemumgehung besteht darin, den Konstruktor nicht zu verwenden (oder zumindest getInstance () darin nicht zu verwenden), sondern explizit eine "init" -Funktion in der Klasse zu haben, um Ihre Aktionen und dergleichen einzurichten. So was:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Mit so etwas wird am Ende der Datei, nachdem alle Klassen definiert wurden, das Instanziieren des Plugins so einfach wie folgt:
ExamplePlugin::init();
Init fügt Ihre Aktionen hinzu und ruft dabei getInstance () auf, das die Klasse instanziiert und sicherstellt, dass nur eine von ihnen existiert. Wenn Sie keine init-Funktion haben, würden Sie dies tun, um die Klasse stattdessen zunächst zu instanziieren:
ExamplePlugin::getInstance();
Um die ursprüngliche Frage zu beantworten, können Sie diesen Aktionshaken von außen (auch bekannt als in einem anderen Plugin) folgendermaßen entfernen:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Setzen Sie das in etwas ein, das an den plugins_loaded
Aktionshaken angehängt ist, und es macht die Aktion rückgängig, die vom ursprünglichen Plugin angehängt wird.