Chaque fois qu'un plugin crée un new MyClass();
, il doit l'affecter à une variable portant un nom unique. De cette façon, l'instance de la classe est accessible.
Donc, s'il le faisait $myclass = new MyClass();
, vous pourriez faire ceci:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Cela fonctionne car les plugins sont inclus dans l'espace de noms global. Par conséquent, les déclarations de variables implicites dans le corps principal d'un plugin sont des variables globales.
Si le plugin n'enregistre pas l'identifiant de la nouvelle classe quelque part , techniquement, c'est un bug. L'un des principes généraux de la programmation orientée objet est que les objets qui ne sont pas référencés par une variable quelque part sont sujets à nettoyage ou à élimination.
Maintenant, PHP en particulier ne fait pas cela comme le ferait Java, parce que PHP est en quelque sorte une implémentation POO à demi-arsée. Les variables d'instance sont juste des chaînes avec des noms d'objet uniques, en quelque sorte. Ils fonctionnent uniquement en raison de la manière dont l'interaction du nom de la fonction variable fonctionne avec l' ->
opérateur. Donc, faire new class()
peut parfaitement fonctionner, simplement bêtement. :)
Donc, en bout de ligne, ne faites jamais new class();
. Faites $var = new class();
et rendez ce $ var accessible d'une certaine manière pour que d'autres bits le référencent.
Edit: ans plus tard
Une chose que j'ai vu beaucoup de plugins est d'utiliser quelque chose de similaire au motif "Singleton". Ils créent une méthode getInstance () pour obtenir l'instance unique de la classe. C'est probablement la meilleure solution que j'ai vue. Exemple de plugin:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
La première fois que getInstance () est appelé, il instancie la classe et enregistre son pointeur. Vous pouvez l'utiliser pour accrocher des actions.
Un problème avec ceci est que vous ne pouvez pas utiliser getInstance () dans le constructeur si vous utilisez une telle chose. En effet, new appelle le constructeur avant de définir l'instance $. L'appel de getInstance () à partir du constructeur conduit donc à une boucle infinie et interrompt tout.
Une solution de contournement consiste à ne pas utiliser le constructeur (ou, du moins, à ne pas utiliser getInstance () dans celui-ci), mais à avoir explicitement une fonction "init" dans la classe pour configurer vos actions, etc. Comme ça:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Avec quelque chose comme ceci, à la fin du fichier, une fois que la classe a été définie et telle, instancier le plugin devient aussi simple que cela:
ExamplePlugin::init();
Init commence à ajouter vos actions et appelle ainsi getInstance (), qui instancie la classe et s'assure que seul l'un d'entre eux existe. Si vous n'avez pas de fonction init, faites ceci pour instancier initialement la classe:
ExamplePlugin::getInstance();
Pour répondre à la question initiale, supprimer ce crochet d'action de l'extérieur (c'est-à-dire dans un autre plugin) peut alors être effectué comme suit:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Mettez cela dans quelque chose qui est accroché au plugins_loaded
crochet d’action et cela annulera l’action accrochée par le plugin original.