Функция remove_action() позволяет отключить callback, ранее добавленный с помощью add_action(). Это полезно, когда нужно изменить поведение плагина или темы без редактирования их файлов.
На практике remove_action() часто «не работает», потому что WordPress ищет callback по точному набору параметров: имени хука, функции или методу, приоритету и моменту выполнения. Если хотя бы один элемент не совпадает, удаление не произойдёт.
Как работает remove_action()
При вызове add_action() WordPress сохраняет callback во внутреннем списке конкретного хука. В этой записи учитываются имя хука, callback и его приоритет. remove_action() не удаляет «похожую» функцию, а ищет именно ту запись, которая была добавлена ранее.
Сигнатура функции выглядит так:
- имя хука должно полностью совпадать;
- функция, метод или объект должны совпадать;
- приоритет должен быть таким же, как в add_action();
- удаление нужно выполнить после регистрации callback, но до его фактического запуска.
remove_action( string $hook_name, callable $callback, int $priority = 10 ): bool;
Неправильный приоритет — самая распространённая причина
Если при добавлении callback был указан приоритет 20, удалить его с приоритетом 10 нельзя. Значение по умолчанию в remove_action() равно 10, поэтому отсутствие третьего аргумента часто становится причиной ошибки.
Важно также различать момент регистрации и момент выполнения. В примере ниже callback регистрируется на init с приоритетом 20, а удаляется на том же хуке с приоритетом 30. При первом запуске init callback с приоритетом 20 уже успеет выполниться. Удаление повлияет только на следующие вызовы этого хука, если они вообще произойдут.
- Чтобы callback не выполнился, его нужно удалить до того, как WordPress дойдёт до его приоритета.
- Если сторонний код добавляет callback во время init, удаление с более высоким приоритетом не отменит уже выполненное действие.
- Для одноразовых хуков, таких как init, удаление с опозданием обычно не даёт ожидаемого результата.
add_action( 'init', 'plugin_register_post_type', 20 );
// Этот код выполнится после callback с приоритетом 20.
add_action( 'init', function () {
remove_action( 'init', 'plugin_register_post_type', 20 );
}, 30 );
Проверьте, когда именно добавляется callback
Вызов remove_action() должен произойти после add_action(), иначе в WordPress ещё не будет записи, которую нужно удалить. В то же время удаление должно выполняться достаточно рано, чтобы callback не успел сработать.
Например, плагин может регистрировать свой callback на plugins_loaded, init, wp_loaded или специальном хуке. Если ваш код выполняется раньше, callback ещё не существует. Если значительно позже — он уже мог сработать.
Лучший подход — найти в коде плагина строку add_action() и определить всю цепочку: где она выполняется, какой у неё приоритет и на каком хуке можно безопасно вмешаться.
- Если callback добавляется во время plugins_loaded, код для его удаления должен выполниться после этого момента.
- Если callback добавляется на init, удаление на init с более высоким приоритетом может оказаться запоздалым для текущего запуска.
- Если действие уже изменило данные или зарегистрировало тип записи, remove_action() не вернёт систему в предыдущее состояние — он лишь предотвратит будущие вызовы.
add_action( 'plugins_loaded', function () {
remove_action( 'some_hook', 'plugin_callback', 10 );
}, 20 );
Как проверить, зарегистрирован ли callback
Для быстрой проверки используйте has_action(). Функция возвращает приоритет callback, если он найден, или false, если такой записи нет. Поскольку add_action() в WordPress работает через тот же внутренний механизм, has_action() подходит и для диагностики action.
Проверку лучше выполнять непосредственно перед remove_action(), а результат записывать в журнал. Это помогает отличить неправильный callback от проблемы с моментом выполнения.
- Значение false означает, что callback с таким описанием не найден.
- Число означает фактически зарегистрированный приоритет.
- Если приоритет отличается от ожидаемого, передайте в remove_action() фактический приоритет.
$priority = has_action( 'init', 'plugin_register_post_type' );
error_log( var_export( $priority, true ) );
if ( false !== $priority ) {
remove_action( 'init', 'plugin_register_post_type', $priority );
}
Методы объектов и анонимные функции
Callback часто принадлежит не глобальной функции, а объекту. В таком случае нужно передать тот же экземпляр объекта. Создание нового экземпляра того же класса и метода не поможет: для WordPress это другой callable.
Для статического метода используется другой синтаксис, чем для метода конкретного объекта. Также нужно учитывать пространства имён: имя функции может содержать префикс namespace.
- Для метода объекта требуется тот же экземпляр.
- Для статического метода используйте [ ClassName::class, 'method' ] или соответствующую строку.
- Анонимную функцию можно удалить только в том случае, если при регистрации она была сохранена в переменной.
- Создать новую closure с идентичным кодом недостаточно: это будет другой объект функции.
$plugin_object = new Plugin_Class();
add_action( 'init', [ $plugin_object, 'register' ], 10 );
// Требуется именно тот же $plugin_object.
remove_action( 'init', [ $plugin_object, 'register' ], 10 );
$callback = function () {
// Действие.
};
add_action( 'init', $callback, 10 );
remove_action( 'init', $callback, 10 );
Action и filter: что именно нужно удалять
В WordPress add_action() и add_filter() используют общий внутренний механизм. Однако на уровне API всё же стоит применять соответствующую пару: callback, добавленный через add_action(), удаляйте с помощью remove_action(), а callback из add_filter() — с помощью remove_filter(). Так код будет понятнее и менее подвержен ошибкам.
Ключевое значение имеет не название функции удаления, а точное совпадение имени хука, callback и приоритета. Если callback был добавлен на filter, проверяйте именно этот filter и не путайте его с action с похожим названием.
Параметр accepted_args не нужно передавать в remove_action() или remove_filter(). Для поиска callback WordPress использует хук, callable и приоритет.
- Проверьте, не перепутаны ли названия похожих хуков.
- Не пытайтесь удалить filter через другой хук с тем же callback.
- Если callback добавляется несколько раз с разными приоритетами, каждую запись нужно удалять отдельно.
add_filter( 'the_content', 'plugin_modify_content', 20 );
remove_filter( 'the_content', 'plugin_modify_content', 20 );
Практический алгоритм диагностики
Если remove_action() не даёт результата, не стоит сразу менять приоритет наугад. Последовательная проверка поможет быстрее найти причину.
- Найдите исходный вызов add_action() в коде плагина или темы.
- Скопируйте точное имя хука и callback.
- Проверьте приоритет — если он не указан, это 10.
- Определите, является ли callback обычной функцией, методом объекта, статическим методом или closure.
- Проверьте, выполняется ли ваш код после регистрации callback, но до его запуска.
- Используйте has_action() и проверьте его результат.
- Убедитесь, что действие не успело выполниться раньше и изменить состояние системы.
- После тестирования ограничьте удаление нужным условием, окружением или конкретным контекстом.
add_action( 'wp_loaded', function () {
$priority = has_action( 'some_hook', [ $same_object, 'method' ] );
error_log( 'Callback priority: ' . var_export( $priority, true ) );
if ( false !== $priority ) {
remove_action( 'some_hook', [ $same_object, 'method' ], $priority );
}
}, 20 );
Безопасное использование remove_action()
Глобальное удаление callback может повлиять на все страницы и функции сайта. Перед изменением проверьте, зачем нужно это действие, не зависит ли от него другой код и в каком контексте его требуется отключить.
Если изменение необходимо только для административной части, конкретного типа записи или отдельного шаблона, добавьте соответствующее условие. Это снизит риск побочных эффектов после обновления плагина.
- Не редактируйте файлы стороннего плагина — вынесите код в собственный плагин или тему.
- Тестируйте изменения на staging-среде.
- Во время диагностики записывайте результат проверки в журнал, но не оставляйте лишнее логирование в production.
- После обновления плагина повторно проверьте имя callback, приоритет и способ его регистрации.
add_action( 'wp', function () {
if ( ! is_singular( 'product' ) ) {
return;
}
remove_action( 'some_hook', 'plugin_callback', 10 );
}, 20 );
Частые вопросы
Можно ли вызвать remove_action() до add_action()?
Обычно нет. Если callback ещё не зарегистрирован, WordPress не найдёт его и ничего не удалит. При этом недостаточно вызвать remove_action() после add_action() — нужно сделать это до фактического запуска callback.
Почему remove_action() возвращает true, но действие всё равно выполняется?
Чаще всего callback был добавлен несколько раз, например с разными приоритетами, или он уже успел выполниться до удаления. Проверьте все регистрации и момент вызова.
Можно ли удалить метод объекта, создав новый экземпляр класса?
Нет. Для обычного метода нужен тот же экземпляр, который был передан в add_action(). Новый объект с тем же классом и методом имеет другую идентичность.
Как удалить анонимную функцию?
Нужно сохранить closure в переменной во время регистрации, а затем передать эту же переменную в remove_action(). Повторно объявленная анонимная функция не будет тем же callback.
Можно ли использовать remove_action() для callback, добавленного через add_filter()?
Внутренне эти API используют общий механизм, но для ясности кода применяйте remove_filter() для filter и remove_action() для action. В любом случае должны совпадать хук, callback и приоритет.
Вывод
remove_action() работает только при точном совпадении всех параметров и правильном моменте выполнения. Проверьте исходный add_action(), приоритет, тип callback и конкретный экземпляр объекта.
Если callback уже сработал, его удаление не отменит выполненное действие. Поэтому при диагностике важно определить не только то, что нужно удалить, но и момент, когда это нужно сделать.