Всякий раз, когда плагин создает new MyClass();
, он должен назначить его переменной с уникальным именем. Таким образом, экземпляр класса доступен.
Так что, если он делал $myclass = new MyClass();
, то вы могли бы сделать это:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Это работает, потому что плагины включены в глобальное пространство имен, поэтому неявные объявления переменных в основной части плагина являются глобальными переменными.
Если плагин не сохраняет идентификатор нового класса где-то , то технически это ошибка. Одним из общих принципов объектно-ориентированного программирования является то, что объекты, на которые не ссылается какая-либо переменная, подлежат очистке или удалению.
В частности, PHP, в частности, делает это не так, как Java, потому что PHP - это наполовину реализация ООП. Переменные экземпляра - это просто строки с уникальными именами объектов, что-то вроде этого. Они работают только из-за способа взаимодействия имени переменной функции с ->
оператором. Так что просто делать new class()
действительно может работать отлично, просто глупо. :)
Итак, суть, никогда не делай new class();
. Сделайте $var = new class();
и сделайте этот $ var доступным для других битов, чтобы ссылаться на него.
Изменить: годы спустя
Одна вещь, которую я видел во многих плагинах, это использование чего-то похожего на шаблон «Синглтон». Они создают метод getInstance (), чтобы получить единственный экземпляр класса. Это, наверное, лучшее решение, которое я видел. Пример плагина:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
При первом вызове getInstance () он создает экземпляр класса и сохраняет его указатель. Вы можете использовать это, чтобы подключить действия.
Одна из проблем заключается в том, что вы не можете использовать getInstance () внутри конструктора, если используете такую вещь. Это потому, что new вызывает конструктор перед установкой $ instance, поэтому вызов getInstance () из конструктора приводит к бесконечному циклу и прерывает все.
Один из обходных путей - не использовать конструктор (или, по крайней мере, не использовать внутри него getInstance ()), но явно иметь функцию «init» в классе для настройки ваших действий и тому подобного. Нравится:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Что-то вроде этого, в конце файла, после того, как класс был полностью определен и тому подобное, создание плагина становится таким простым:
ExamplePlugin::init();
Init начинает добавлять ваши действия и при этом вызывает getInstance (), который создает экземпляр класса и проверяет, существует ли только одно из них. Если у вас нет функции инициализации, вы должны сделать это для первоначального создания экземпляра класса:
ExamplePlugin::getInstance();
Чтобы ответить на исходный вопрос, удаление этого хука действия извне (иначе в другом плагине) может быть сделано следующим образом:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Поместите это во что-то, зацепленное за plugins_loaded
крючок действия, и оно отменит действие, зацепленное оригинальным плагином.