Cuando 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 , entonces 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, ya que PHP es más o menos una implementación OOP de media ejecución. Las variables de instancia son solo cadenas con nombres de objetos únicos en ellas, algo así. Solo funcionan debido a la forma en que funciona la interacción variable de nombre de función con el operador ->
. Así que solo hacer new class()
puede funcionar perfectamente, solo de forma estúpida. :)
Entonces, en conclusión, nunca hagamos new class();
. Haga $var = new class();
y haga que $ var sea accesible de alguna manera para que otros bits lo referencian.
Editar: años más tarde
Una cosa que he visto hacer a muchos complementos es usar algo similar al patrón "Singleton". Crean un método getInstance () para obtener la instancia única de la clase. Esta es probablemente la mejor solución que he visto. Ejemplo de complemento:
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. Puedes usar eso para enganchar acciones.
Un problema con esto es que no puedes usar getInstance () dentro del constructor si usas tal cosa. Esto se debe a que el nuevo constructor llama al constructor antes de establecer la instancia $, por lo que llamar a getInstance () desde el constructor conduce a un bucle infinito y 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. Así:
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 se haya definido la clase y todo lo anterior, crear una instancia del complemento se vuelve tan simple como esto:
ExamplePlugin::init();
Init comienza a agregar tus 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 de inicio, haría esto para crear una instancia de la clase inicialmente:
ExamplePlugin::getInstance();
Para abordar la pregunta original, eliminar ese enlace de acción desde el exterior (también conocido en otro complemento) se puede hacer de la siguiente manera:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Coloca eso en algo enganchado al gancho de acción plugins_loaded
y deshará la acción enganchada por el complemento original.