WordPress

akcje – usuń_akcję lub usuń_filter z klasami zewnętrznymi?

  • 9 grudnia, 2011
  • 3 min read
akcje – usuń_akcję lub usuń_filter z klasami zewnętrznymi?


Ilekroć wtyczka tworzy plik new MyClass();, powinien przypisać ją do zmiennej o unikatowej nazwie. W ten sposób instancja klasy będzie 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 ukryte deklaracje zmiennych w głównej części wtyczki są zmiennymi globalnymi.

Jeśli wtyczka nie zapisze identyfikatora nowej klasy gdzieś, więc technicznie rzecz biorąc, jest to błąd. Jedną z ogólnych zasad programowania obiektowego jest to, że obiekty, do których nie odwołuje się żadna zmienna, podlegają czyszczeniu lub eliminacji.

W szczególności PHP nie robi tego tak, jak zrobiłaby to Java, ponieważ PHP jest w pewnym sensie niedopracowaną implementacją OOP. Zmienne instancji to po prostu ciągi znaków z unikalnymi nazwami obiektów. Działają one tylko ze względu na sposób, w jaki interakcja nazwy funkcji zmiennej współpracuje z plikiem -> operator. Więc po prostu robię new class() rzeczywiście może działać idealnie, tylko głupio. 🙂

Podsumowując, nigdy tego nie rób new class();. Do $var = new class(); i udostępnij ten $var w jakiś sposób, aby inne bity mogły się do niego odwoływać.

Warto przeczytać!  Względne bezpieczeństwo różnych wydań WordPress

Edycja: lata później

Jedną z rzeczy, które widziałem w wielu wtyczkach, jest użycie czegoś podobnego do wzorca „Singleton”. Tworzą metodę getInstance(), aby uzyskać pojedynczą instancję klasy. To prawdopodobnie 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 metody getInstance() tworzy ona instancję klasy i zapisuje jej wskaźnik. Możesz tego użyć do podpięcia działań.

Jednym z problemów jest to, że nie możesz użyć funkcji getInstance() wewnątrz konstruktora, jeśli używasz czegoś takiego. Dzieje się tak, ponieważ new wywołuje konstruktor przed ustawieniem $instance, więc wywołanie getInstance() z konstruktora prowadzi do nieskończonej pętli i wszystko psuje.

Jednym z rozwiązań jest nieużywanie konstruktora (lub przynajmniej nie używanie w nim funkcji getInstance()), ale jawne posiadanie w klasie funkcji „init” umożliwiającej konfigurowanie działań itp. Lubię to:

public static function init() {
    add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}

W przypadku czegoś takiego na końcu pliku, po zdefiniowaniu całej klasy, utworzenie instancji wtyczki staje się tak proste, jak to:

ExamplePlugin::init();

Init zaczyna dodawać Twoje akcje i w ten sposób wywołuje metodę getInstance(), która tworzy instancję klasy i upewnia się, że tylko jedna z nich istnieje. Jeśli nie masz funkcji init, możesz to zrobić, aby początkowo utworzyć instancję klasy:

ExamplePlugin::getInstance();

Aby odpowiedzieć na pierwotne pytanie, usunięcie tego haka akcji z zewnątrz (czyli w innej wtyczce) można następnie wykonać w następujący sposób:

remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );

Umieść to w czymś podłączonym do plugins_loaded hak akcji i cofnie akcję zaczepioną przez oryginalną wtyczkę.

Warto przeczytać!  pętla — Niestandardowa paginacja archiwum typu postu z motywem HTML5Blank?


Źródło