Щоразу, коли плагін створює a new MyClass();
, він повинен присвоювати йому унікальну названу змінну. Таким чином, доступний екземпляр класу.
Отже, якщо він робив $myclass = new MyClass();
, то ви могли б зробити це:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Це працює тому, що плагіни включені в глобальний простір імен, тому неявні оголошення змінних в основному корпусі плагіна є глобальними змінними.
Якщо плагін десь не зберігає ідентифікатор нового класу , то технічно це помилка. Одним із загальних принципів об'єктно-орієнтованого програмування є те, що об'єкти, на які десь не посилається якась змінна, підлягають очищенню або усуненню.
Тепер, зокрема, PHP не робить так, як Java, тому що PHP - це напівскладова реалізація OOP. Змінні екземпляра - це просто рядки з унікальними іменами об'єктів, подібними до речі. Вони працюють лише через те, як взаємодія імен змінної функції працює з ->
оператором. Тож просто робити new class()
справді може спрацювати ідеально, просто нерозумно. :)
Отже, підсумок, ніколи не роби new class();
. Зробіть $var = new class();
та зробіть цей $ var доступним якимось чином для інших біт для посилання на нього.
Редагувати: через роки
Одне, що я бачив, як багато плагінів роблять, це використовувати щось подібне до шаблону "Singleton". Вони створюють метод getInstance (), щоб отримати єдиний екземпляр класу. Це, мабуть, найкраще рішення, що я бачив. Приклад плагіна:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
Перший раз, коли викликається getInstance (), він створює екземпляр класу та зберігає його вказівник. Ви можете використовувати це для підключення до дій.
Одна з проблем полягає в тому, що ви не можете використовувати getInstance () всередині конструктора, якщо ви використовуєте таку річ. Це тому, що новий виклик конструктора перед встановленням екземпляра $, тому виклик getInstance () від конструктора призводить до нескінченного циклу і все порушує.
Одне вирішення полягає в тому, щоб не використовувати конструктор (або, принаймні, не використовувати getInstance () всередині нього), а явно мати функцію "init" у класі для налаштування ваших дій тощо. Подобається це:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Щось подібне, в кінці файлу, після того, як клас був визначений і такий, інстанціювання плагіна стає таким же простим, як це:
ExamplePlugin::init();
Init починає додавати ваші дії, і при цьому робить виклик getInstance (), який створює екземпляр класу і переконує, що існує лише одна з них. Якщо у вас немає функції init, ви зробите це для того, щоб ініціювати клас спочатку замість цього:
ExamplePlugin::getInstance();
Щоб вирішити оригінальне запитання, видалення цього гака ззовні (так само в іншому плагіні) можна зробити так:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Помістіть це в щось, підключене до plugins_loaded
гака дії, і це скасує дію, підключене оригінальним плагіном.