Action виконує побічну дію в певній точці життєвого циклу й нічого не повертає; filter отримує значення, змінює його й обовʼязково повертає.
Як питають
Що станеться, якщо фільтр нічого не поверне?
Як контролювати порядок виконання кількох хуків?
Чому після активації плагіна зник контент сторінок?
хукиactionsfilters
Пояснення
Хуки — це спосіб WordPress дозволити чужому коду втрутитись у свій без правки ядра. Action виконує побічну дію в певній точці: щось вивести, записати в лог, надіслати лист. Він нічого не повертає. Filter отримує значення, наприклад заголовок або контент, змінює його й повертає далі по ланцюжку. Внутрішньо обидва живуть в одному реєстрі WP_Hook, і add_action є обгорткою над add_filter; різниця лише в тому, чи використовується результат.
Найчастіша помилка новачків — фільтр без return. Колбек повертає null, null іде далі по ланцюжку і в код, який викликав apply_filters, і на сайті зникають заголовки, контент чи ціни. WordPress не перевіряє тип результату, тому помилка тиха.
Порядок задається пріоритетом: менше число виконується раніше, за замовчуванням 10. Якщо два плагіни фільтрують the_content з однаковим пріоритетом, результат залежить від порядку завантаження, і саме звідси більшість конфліктів. Четвертий аргумент accepted_args визначає, скільки параметрів отримає колбек; без нього другий аргумент фільтра не прийде.
Щоб зняти чужий хук, remove_filter потребує те саме імʼя, той самий колбек і той самий пріоритет. Тому у власних плагінах хуки краще реєструвати іменованими функціями або методами з доступним екземпляром, а не анонімними замиканнями.
КодPHP
// Action: побічна дія, нічого не повертає
add_action('wp_footer', function (): void {
echo '<!-- rendered at '.date('c').' -->';
});
// Filter: отримує значення й ОБОВʼЯЗКОВО повертає
add_filter('the_title', function (string $title, int $postId): string {
return is_admin() ? $title : trim($title).' ✦';
}, 10, 2); // пріоритет 10, колбек приймає 2 аргументи
// Класична помилка: контент зникає, бо повертається null
add_filter('the_content', function (string $content): void {
str_replace('[year]', date('Y'), $content); // немає return
});
// Свій код стає розширюваним
function shop_shipping_cost(int $cents): int
{
return (int) apply_filters('shop_shipping_cost', $cents);
}
do_action('shop_order_shipped', $orderId);
// Знімаємо чужий хук: імʼя + колбек + пріоритет мають збігатись
add_action('init', fn () => remove_filter('the_content', 'wpautop', 10), 20);
Що хоче почути інтервʼюер
Що обидва механізми побудовані на одному реєстрі: add_filter і add_action це та сама функція, різниця в тому, чи використовується повернене значення.
Що забутий return у фільтрі повертає null, і саме так зникають контент, заголовки чи ціни після активації плагіна.
Що пріоритет визначає порядок: менше число виконується раніше, за замовчуванням 10, і конфлікти плагінів часто саме через однакові пріоритети.
Що четвертий аргумент accepted_args обмежує, скільки параметрів отримає колбек, і без нього другий аргумент фільтра просто не прийде.
Що remove_action і remove_filter потребують той самий колбек і пріоритет, тому анонімні функції в хуках не можна зняти.
Типові помилки
Казати, що це синоніми або що різниця лише в назві.
Забувати return у фільтрі й ламати вивід усього сайту.
Використовувати action там, де треба змінити значення: писати в глобальну змінну замість повернення з фільтра.
Вішати хуки на анонімні функції або в неправильний момент, наприклад до plugins_loaded, коли потрібні класи ще не завантажені.
Не вказувати accepted_args і дивуватись, що $post чи $context у колбеку відсутній.
ПОРАДА
Додайте, що пріоритет хука визначає порядок, і конфлікти плагінів найчастіше саме через однакові пріоритети. Згадайте apply_filters і do_action як точки, де ваш код сам стає розширюваним.
Додаткові питанняЗ ВІДПОВІДЯМИ
Колбек поверне null, і саме null піде далі по ланцюжку фільтрів і в код, який викликав apply_filters. Для the_content це порожній контент, для the_title порожній заголовок, для woocommerce_product_get_price нульова ціна. WordPress не валідує тип поверненого значення, тому помилка тиха.
Третім аргументом add_action і add_filter є пріоритет: колбеки виконуються від меншого до більшого, за замовчуванням 10, з однаковим пріоритетом у порядку реєстрації. Щоб гарантовано спрацювати після плагіна, який використовує 10, ставлять 20 або PHP_INT_MAX. Перевірити, що вже підписано на хук, можна через глобальний $wp_filter.
do_action викликає всі колбеки й нічого не повертає; apply_filters передає перший аргумент через ланцюжок колбеків і повертає результат останнього. Внутрішньо обидва працюють з одним реєстром WP_Hook. У власному плагіні apply_filters робить значення налаштовуваним, а do_action дає іншим плагінам точку, куди підвісити дію.
remove_action або remove_filter з тим самим імʼям хука, тим самим колбеком і тим самим пріоритетом. Для методів обʼєкта потрібен саме той екземпляр, тому плагіни, які реєструють хуки через $this в конструкторі без глобального доступу до обʼєкта, зняти складно. Робити це слід після того, як плагін зареєстрував хук, наприклад на init з більшим пріоритетом.