Cada vez que un complemento crea un new MyClass();
, debe asignarlo a una variable con un nombre único. De esa manera, la instancia de la clase es accesible.
Entonces, si él estaba haciendo $myclass = new MyClass();
, entonces podrías hacer esto:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Esto funciona porque los complementos se incluyen en el espacio de nombres global, por lo que las declaraciones de variables implícitas en el cuerpo principal de un complemento son variables globales.
Si el complemento no guarda el identificador de la nueva clase en algún lugar , técnicamente, eso es un error. Uno de los principios generales de la Programación Orientada a Objetos es que los objetos a los que no hace referencia alguna variable en algún lugar están sujetos a limpieza o eliminación.
Ahora, PHP en particular no hace esto como lo haría Java, porque PHP es una implementación de OOP a medias. Las variables de instancia son solo cadenas con nombres de objeto únicos, algo así. Solo funcionan debido a la forma en que la interacción del nombre de la función variable funciona con el ->
operador. Tan solo hacer new class()
puede funcionar perfectamente, solo estúpidamente. :)
Entonces, en resumen, nunca lo hagas new class();
. Haga $var = new class();
y haga que $ var sea accesible de alguna manera para que otros bits lo hagan referencia.
Editar: años después
Una cosa que he visto hacer muchos complementos es usar algo similar al patrón "Singleton". Crean un método getInstance () para obtener la única instancia de la clase. Esta es probablemente la mejor solución que he visto. Plugin de ejemplo:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
La primera vez que se llama a getInstance (), crea una instancia de la clase y guarda su puntero. Puede usar eso para enganchar acciones.
Un problema con esto es que no puede usar getInstance () dentro del constructor si usa tal cosa. Esto se debe a que el nuevo llama al constructor antes de establecer la instancia $, por lo que llamar a getInstance () desde el constructor conduce a un bucle infinito y lo rompe todo.
Una solución alternativa es no usar el constructor (o, al menos, no usar getInstance () dentro de él), sino tener explícitamente una función "init" en la clase para configurar sus acciones y demás. Me gusta esto:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Con algo como esto, al final del archivo, después de que la clase se haya definido y tal, crear instancias del complemento se vuelve tan simple como esto:
ExamplePlugin::init();
Init comienza a agregar sus acciones, y al hacerlo llama a getInstance (), que crea una instancia de la clase y se asegura de que solo exista una de ellas. Si no tiene una función init, debería hacer esto para instanciar la clase inicialmente en su lugar:
ExamplePlugin::getInstance();
Para abordar la pregunta original, eliminar ese gancho de acción desde el exterior (también conocido como, en otro complemento) se puede hacer así:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Ponga eso en algo conectado al plugins_loaded
gancho de acción y deshacerá la acción que está siendo enganchada por el complemento original.