Ogni volta che un plugin crea un new MyClass();
, dovrebbe assegnarlo a una variabile con un nome univoco. In questo modo, l'istanza della classe è accessibile.
Quindi, se lo stesse facendo $myclass = new MyClass();
, allora potresti farlo:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Questo funziona perché i plugin sono inclusi nello spazio dei nomi globale, quindi le dichiarazioni di variabili implicite nel corpo principale di un plugin sono variabili globali.
Se il plugin non salva l'identificatore della nuova classe da qualche parte , quindi tecnicamente, questo è un bug. Uno dei principi generali della programmazione orientata agli oggetti è che gli oggetti a cui non viene fatto riferimento da qualche variabile da qualche parte sono soggetti a pulizia o eliminazione.
Ora, in particolare PHP non fa ciò come farebbe Java, poiché PHP è una sorta di implementazione OOP a metà corsa. Le variabili di istanza sono solo stringhe con nomi di oggetti univoci, una sorta di cosa. Funzionano solo per il modo in cui l'interazione con il nome della funzione variabile funziona con l' ->
operatore. Quindi semplicemente fare new class()
può davvero funzionare perfettamente, semplicemente stupidamente. :)
Quindi, in conclusione, non farlo mai new class();
. Fai $var = new class();
e rendi $ var accessibile in qualche modo per fare riferimento ad altri bit.
Modifica: anni dopo
Una cosa che ho visto fare molti plugin è usare qualcosa di simile al modello "Singleton". Creano un metodo getInstance () per ottenere la singola istanza della classe. Questa è probabilmente la migliore soluzione che abbia mai visto. Esempio di plugin:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
La prima volta che viene chiamato getInstance (), crea un'istanza della classe e salva il puntatore. Puoi usarlo per agganciare le azioni.
Un problema con questo è che non puoi usare getInstance () all'interno del costruttore se usi una cosa del genere. Questo perché il nuovo chiama il costruttore prima di impostare l'istanza $, quindi chiamare getInstance () dal costruttore porta a un ciclo infinito e interrompe tutto.
Una soluzione alternativa è quella di non usare il costruttore (o, almeno, non usare getInstance () al suo interno), ma di avere esplicitamente una funzione "init" nella classe per impostare le tue azioni e simili. Come questo:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Con qualcosa del genere, alla fine del file, dopo che la classe è stata definita e tale, istanziare il plugin diventa semplice come questo:
ExamplePlugin::init();
Init inizia ad aggiungere le tue azioni, e così facendo chiama getInstance (), che crea un'istanza della classe e si assicura che ne esista solo una. Se non si dispone di una funzione init, si dovrebbe fare ciò per creare un'istanza della classe inizialmente:
ExamplePlugin::getInstance();
Per rispondere alla domanda originale, rimuovere quel gancio di azione dall'esterno (aka, in un altro plugin) può quindi essere fatto in questo modo:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Inseriscilo in qualcosa agganciato al plugins_loaded
gancio di azione e annullerà l'azione che viene agganciata dal plugin originale.