Ilekroć wtyczka tworzy new MyClass();
, powinna przypisać ją do zmiennej o unikalnej nazwie. W ten sposób instancja klasy jest dostępna.
Więc jeśli to robił $myclass = new MyClass();
, możesz to zrobić:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Działa to, ponieważ wtyczki są zawarte w globalnej przestrzeni nazw, więc niejawne deklaracje zmiennych w głównej części wtyczki są zmiennymi globalnymi.
Jeśli wtyczka nie zapisuje gdzieś identyfikatora nowej klasy , technicznie to błąd. Jedną z ogólnych zasad programowania obiektowego jest to, że obiekty, do których nie odwołuje się jakaś zmienna, podlegają czyszczeniu lub eliminacji.
Teraz PHP w szczególności nie robi tego tak, jak zrobiłby to Java, ponieważ PHP jest w pewnym sensie implementacją OOP na wpół arse. Zmienne instancji to po prostu ciągi znaków z unikalnymi nazwami obiektów. Działają tylko ze względu na sposób, w jaki interakcja nazwy funkcji zmiennej działa z ->
operatorem. Więc samo robienie new class()
może naprawdę działać idealnie, po prostu głupio. :)
Podsumowując, nigdy nie rób new class();
. Zrób $var = new class();
i udostępnij ten $ var w jakiś sposób, aby inne bity mogły się do niego odwoływać.
Edycja: lata później
Jedną z rzeczy, które widziałem wiele wtyczek, jest użycie czegoś podobnego do wzorca „Singleton”. Tworzą metodę getInstance (), aby uzyskać pojedyncze wystąpienie klasy. To chyba najlepsze rozwiązanie, jakie widziałem. Przykładowa wtyczka:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
Przy pierwszym wywołaniu getInstance () tworzy instancję klasy i zapisuje jej wskaźnik. Możesz go użyć, aby włączyć działania.
Jednym z problemów jest to, że nie można używać getInstance () wewnątrz konstruktora, jeśli używa się takiej rzeczy. Wynika to z faktu, że nowe wywołuje konstruktor przed ustawieniem instancji $, więc wywołanie getInstance () z konstruktora prowadzi do nieskończonej pętli i psuje wszystko.
Jednym z obejść tego problemu jest nieużywanie konstruktora (lub przynajmniej nie używanie w nim getInstance ()), ale jawne posiadanie funkcji „init” w klasie do konfigurowania akcji i tym podobnych. Lubię to:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Z czymś takim na końcu pliku, po zdefiniowaniu całej klasy i utworzeniu instancji wtyczki staje się tak proste:
ExamplePlugin::init();
Init zaczyna dodawać twoje akcje, a tym samym wywołuje metodę getInstance (), która tworzy instancję klasy i upewnia się, że istnieje tylko jedna z nich. Jeśli nie masz funkcji init, zrób to, aby początkowo utworzyć instancję klasy:
ExamplePlugin::getInstance();
Aby odpowiedzieć na pierwotne pytanie, można usunąć hak akcji z zewnątrz (inaczej w innej wtyczce) w następujący sposób:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Umieść to w czymś zaczepionym do plugins_loaded
haka akcji, a cofnie akcję zaczepioną przez oryginalną wtyczkę.