Дії WordPress: Повний посібник розробника з Hooks API
WordPress Actions — це основний компонент Hooks API, який дозволяє розробникам виконувати власні функції в точно визначених точках під час життєвого циклу запиту WordPress — без будь-яких змін у файлах ядра. Коли спрацьовує хук дії, кожна функція, зареєстрована для цього хука, виконується в порядку пріоритету, забезпечуючи модульну, зручну в обслуговуванні та безпечну для оновлень кастомізацію.
Якщо ви створюєте плагін, розробляєте тему або керуєте самостійно розгорнутою інсталяцією WordPress у середовищі VPS Hosting, оволодіння Actions є обов’язковим. Саме вони є основним механізмом, на якому побудований сам WordPress — а не просто інструментом розширення для сторонніх розробників.
Як WordPress Actions насправді працюють зсередини
WordPress підтримує глобальний реєстр під назвою $wp_filter, який зберігає всі зареєстровані хуки — як дії, так і фільтри. Коли викликається do_action(), WordPress шукає запис цього хука в $wp_filter, сортує зареєстровані колбеки за пріоритетом і виконує їх послідовно.
Критична відмінність, яку багато посібників замовчують: Actions — це «вистрілив і забув». Вони виконують колбеки, але відкидають будь-які значення, що повертаються. Якщо вам потрібно перехопити та змінити дані — це завдання Filters, а не Actions. Плутанина між ними є однією з найпоширеніших архітектурних помилок у розробці плагінів WordPress.
Потік виконання виглядає так:
- Ядро WordPress (або плагін/тема) викликає
do_action( 'hook_name', ...$args ). - WordPress визначає всі колбеки, зареєстровані для
hook_nameз$wp_filter. - Колбеки сортуються за значенням
$priority(за зростанням — менші числа спрацьовують першими). - Кожен колбек викликається з переданими аргументами.
- Значення, що повертаються, мовчки ігноруються.
- Виконання продовжується у вихідному коді після повернення
do_action().
Ця архітектура означає, що погано написаний колбек, зареєстрований для раннього хука на кшталт init, може заблокувати весь запит. Завжди профілюйте колбеки хуків на тестовому середовищі перед розгортанням у продакшн.
Реєстрація Actions за допомогою add_action()
Функція add_action() реєструє PHP-callable для іменованого хука дії. Її повний підпис:
add_action( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1 ): trueПояснення параметрів:
$hook_name — Точний рядковий ідентифікатор хука дії (наприклад, wp_login, save_post).
$callback — Будь-який валідний PHP callable: іменована функція, анонімна функція, статичний метод array( 'MyClass', 'method' ) або метод об’єкта array( $object, 'method' ).
$priority — Порядок виконання відносно інших колбеків на тому самому хуку. За замовчуванням 10. Колбеки з однаковим пріоритетом виконуються в порядку реєстрації.
$accepted_args — Скільки аргументів з do_action() передавати вашому колбеку. За замовчуванням 1. Це значення необхідно встановлювати правильно, інакше ваш колбек отримуватиме скорочені списки аргументів.
Базовий приклад: підключення до wp_login
function notify_admin_on_login( string $user_login, WP_User $user ): void {
$admin_email = get_option( 'admin_email' );
$subject = 'Login Alert: ' . $user_login;
$message = sprintf(
'User "%s" (ID: %d) logged in at %s.',
$user_login,
$user->ID,
current_time( 'mysql' )
);
wp_mail( $admin_email, $subject, $message );
}
// wp_login passes two arguments: $user_login (string) and $user (WP_User object)
add_action( 'wp_login', 'notify_admin_on_login', 10, 2 );
Зверніть увагу, що accepted_args встановлено в 2. Якщо пропустити це і залишити значення за замовчуванням 1, ваш колбек отримає лише $user_login і ніколи не побачить об’єкт WP_User — це прихована помилка, яку надзвичайно важко відстежити.
Використання методів об’єктів і замикань
Сучасна розробка для WordPress надає перевагу інкапсуляції логіки всередині класів:
class My_Plugin {
public function __construct() {
add_action( 'init', array( $this, 'register_post_types' ) );
add_action( 'save_post', array( $this, 'handle_save' ), 20, 3 );
}
public function register_post_types(): void {
register_post_type( 'product', array( /* args */ ) );
}
public function handle_save( int $post_id, WP_Post $post, bool $update ): void {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Custom save logic here
}
}
new My_Plugin();
Анонімні замикання теж працюють, але їх неможливо видалити за допомогою remove_action() пізніше, оскільки PHP не може надійно порівнювати посилання на анонімні функції. Використовуйте іменовані методи, коли вам потрібна можливість скасувати реєстрацію.
Видалення Actions за допомогою remove_action()
Ви можете скасувати реєстрацію будь-якого колбека — включно з тими, що додані іншими плагінами або темами — за допомогою remove_action(). Пріоритет має точно збігатися з тим, що використовувався в add_action():
remove_action( 'wp_head', 'wp_generator' ); // Removes WordPress version meta tag
Для методів об’єктів вам потрібне посилання на той самий екземпляр об’єкта:
// Inside a plugin that exposes its instance
global $my_plugin_instance;
remove_action( 'save_post', array( $my_plugin_instance, 'handle_save' ), 20 );
Поширена пастка: виклик remove_action() до того, як виконається оригінальний add_action(). Завжди підключайте видалення до дії, яка спрацьовує після завантаження цільового плагіна — зазвичай plugins_loaded або after_setup_theme.
Довідник основних хуків дій WordPress
Наступна таблиця охоплює найбільш операційно значущі хуки дій, контекст їх спрацювання та практичні випадки використання.
Назва хука
Спрацьовує коли
Типові випадки використання
Передані аргументи
muplugins_loaded
Завантажено обов’язкові плагіни
Рання ініціалізація, константи
0
plugins_loaded
Завантажено всі плагіни
Перевірки сумісності між плагінами
0
init
Після завантаження WP, до заголовків
Реєстрація CPT, таксономій, правил перезапису
0
wp_loaded
Після init, все завантажено
Реєстрація REST API, пізні задачі ініціалізації
0
wp_enqueue_scripts
Завантаження ресурсів фронтенду
Підключення CSS/JS для тем і плагінів
0
wp_head
Всередині тегу <head>
Мета-теги, вбудовані стилі, фрагменти аналітики
0
wp_footer
Перед </body>
Відкладені скрипти, пікселі відстеження
0
admin_init
Завантаження сторінок адмінки
Реєстрація Settings API, перевірки прав доступу
0
admin_enqueue_scripts
Завантаження ресурсів адмінки
Підключення CSS/JS лише для адмінки
1 ($hook_suffix)
save_post
Пост збережено або оновлено
Оновлення мета-даних, синхронізація з зовнішнім API, сповіщення
3
wp_login
Користувач автентифікується
Журналювання аудиту, керування сесіями
2
user_register
Створено нового користувача
Вітальні листи, синхронізація з CRM, призначення ролей
1 ($user_id)
wp_logout
Користувач виходить із системи
Очищення сесій, події аналітики
1 ($user_id)
switch_theme
Змінюється активна тема
Очищення кешу, міграція налаштувань
2
wp_trash_post
Пост переміщено до кошика
Очищення пов’язаних даних, зовнішня синхронізація
1 ($post_id)
rest_api_init
Ініціалізація REST API
Реєстрація власних маршрутів REST
0
template_redirect
До завантаження шаблону
Перенаправлення, контроль доступу
0
do_action() проти do_action_ref_array(): коли що застосовувати
Обидві функції запускають хук дії, але відрізняються способом передачі аргументів.
do_action()
Стандартна функція. Аргументи передаються за значенням — колбеки отримують копії.
do_action( 'my_plugin_after_import', $import_id, $result_count, $errors );
do_action_ref_array()
Аргументи передаються як масив, а об’єкти всередині цього масиву передаються за посиланням (об’єкти PHP завжди передаються подібно до посилань за замовчуванням починаючи з PHP 5). Це насамперед корисно для забезпечення зворотної сумісності або коли вам явно потрібно, щоб колбеки змінювали спільну структуру даних.
$context = array(
'post_id' => 42,
'meta' => array(),
);
do_action_ref_array( 'my_plugin_process_context', array( &$context ) );
// $context['meta'] may now be populated by hooked callbacks
Практична порада: У сучасному PHP (7.4+) поведінкова різниця між ними мінімальна для об’єктів. Використовуйте do_action() за замовчуванням. Звертайтеся до do_action_ref_array() лише при інтеграції з легасі-кодом, який явно його очікує, або коли вам потрібно, щоб колбеки змінювали примітивне значення (наприклад, ціле число), передане за посиланням.
Створення та документування власних хуків дій
При створенні плагіна або теми, призначених для розширення іншими розробниками, вам слід визначати власні хуки дій. Саме так ви надаєте API-поверхню без прямого доступу сторонніх розробників до ваших внутрішніх компонентів.
/**
* Fires after a custom import process completes.
*
* @since 1.0.0
*
* @param int $import_id The ID of the completed import batch.
* @param int $record_count Total number of records processed.
* @param array $errors Array of WP_Error objects, empty on full success.
*/
do_action( 'my_plugin_import_complete', $import_id, $record_count, $errors );
Завжди документуйте свої хуки за допомогою DocBlock безпосередньо над do_action(). Саме це живить генератор документації для розробників WordPress і робить ваш плагін професійного рівня. Сторонні розробники зможуть підключатися чисто:
add_action( 'my_plugin_import_complete', function( int $import_id, int $count, array $errors ) {
if ( ! empty( $errors ) ) {
// Log errors to an external monitoring service
error_log( "Import {$import_id} completed with " . count( $errors ) . ' errors.' );
}
}, 10, 3 );
Actions проти Filters: вичерпне порівняння
Це найважливіша концептуальна відмінність у всьому Hooks API WordPress.
Вимір
Actions
Filters
Основна мета
Виконання побічних ефектів у певний момент часу
Перехоплення та модифікація даних
Значення, що повертається
Повністю ігнорується
Має повертати (змінене) значення
Основна функція
do_action()
apply_filters()
Реєстрація
add_action()
add_filter()
Типове використання
Надсилання email, запис до БД, підключення ресурсів
Зміна вмісту поста, модифікація аргументів запиту
Може скоротити виконання?
Ні (всі колбеки завжди виконуються)
Ні (але можна повернутися раніше всередині колбека)
Мутація даних
Не передбачений патерн
Основна мета
Ключове архітектурне правило: Якщо ви використовуєте add_filter(), але не повертаєте значення з колбека, ви внесли помилку — відфільтроване значення стане null або false залежно від контексту. І навпаки, якщо ви використовуєте add_action() і покладаєтеся на значення, що повертається, ви неправильно використовуєте API.
Конфлікти пріоритетів і порядок виконання
Управління пріоритетами стає критичним у складних екосистемах плагінів. Розглянемо сценарій, де WooCommerce, плагін кешування та ваш власний код підключаються до save_post:
// WooCommerce hooks at priority 10 (default)
// Your inventory sync needs WooCommerce data to already be saved
add_action( 'save_post_product', 'sync_inventory_to_erp', 99 );
// A cache purge should happen last, after all data is written
add_action( 'save_post', 'purge_varnish_cache', 9999 );
Граничні випадки, які варто знати:
Від’ємні пріоритети є валідними в WordPress. add_action( 'init', 'my_func', -1 ) спрацьовує раніше за будь-що з пріоритетом 0 або 10.
Однаковий пріоритет, кілька колбеків — вони виконуються в порядку виклику add_action(). Порядок завантаження плагінів (визначається алфавітно за назвою файлу або плагінами Plugin Order) тому впливає на поведінку.
Рекурсивні хуки — виклик do_action() для того самого хука всередині колбека цього хука технічно можливий, але створює нескінченні цикли. WordPress не захищає від цього.
Пізня реєстрація хука — якщо ви викликаєте add_action( 'init', ... ) після того, як init вже спрацював у поточному запиті, ваш колбек ніколи не виконається в цьому запиті. Це часте джерело помилок у коді, що виконується умовно.
Реальні патерни для продакшну
Патерн 1: Розв’язана система подій
Використовуйте власні дії для розв’язання компонентів плагіна, уникаючи прямих викликів функцій між модулями:
// In your order processing module
do_action( 'my_shop_order_paid', $order_id, $payment_method, $amount );
// In your email module (separate file, no direct dependency)
add_action( 'my_shop_order_paid', 'send_payment_confirmation_email', 10, 3 );
// In your analytics module (separate file, no direct dependency)
add_action( 'my_shop_order_paid', 'track_conversion_event', 20, 3 );
Цей патерн означає, що ви можете повністю вимкнути модуль аналітики, не торкаючись коду обробки замовлень.
Патерн 2: Умовна реєстрація хуків
Уникайте безумовної реєстрації хуків на верхньому рівні. Обмежуйте їх контекстом, де вони потрібні:
add_action( 'admin_init', function() {
// Only register these hooks in the admin context
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_assets' );
add_action( 'save_post', 'my_plugin_validate_custom_fields', 10, 2 );
} );
Патерн 3: Одноразові дії з remove_action() всередині колбека
function my_plugin_run_once(): void {
// Do something that must only happen once per request
update_option( 'my_plugin_initialized', true );
// Deregister itself to prevent re-execution if the hook fires again
remove_action( 'wp_loaded', 'my_plugin_run_once' );
}
add_action( 'wp_loaded', 'my_plugin_run_once' );
Міркування щодо продуктивності в керованих середовищах
На WordPress-інсталяціях з високим трафіком — незалежно від того, чи працюють вони на плані VPS Hosting або Dedicated Server — сукупна вартість погано оптимізованих хуків є відчутною.
Інструменти профілювання для використання:
Плагін Query Monitor: показує кожен хук, що спрацював, кожен виконаний колбек і час виконання кожного колбека.
Xdebug + KCacheGrind: для глибокого профілювання шляхів виконання колбеків.
New Relic APM: для моніторингу продуктивності хуків на рівні продакшну.
Принципи оптимізації:
Переносьте ресурсомісткі операції (запити до бази даних, HTTP-запити, файловий ввід/вивід) з хуків, що спрацьовують при кожному завантаженні сторінки (init, wp_head), до хуків, що спрацьовують лише за необхідності (save_post, user_register).
Використовуйте транзієнти або кешування об’єктів для мемоізації результатів ресурсомістких обчислень всередині колбеків хуків.
Уникайте безумовної реєстрації сотень викликів add_action() під час завантаження плагіна. Реєструйте хуки ліниво лише тоді, коли активна відповідна сторінка адмінки або контекст.
На серверах з увімкненим OPcache (що мають мати всі правильно налаштовані PHP-середовища) накладні витрати самої реєстрації хуків є незначними — вартість полягає в тому, що *роблять* колбеки, а не в реєстрації.
Якщо ви керуєте власним стеком WordPress, забезпечення роботи сервера на PHP 8.1+ з OPcache, кешем байткоду та кешем об’єктів на кшталт Redis або Memcached матиме значно більший вплив на продуктивність, ніж мікрооптимізація пріоритетів хуків.
WordPress Actions у контексті розробки плагінів і тем
При розробці плагіна, призначеного для репозиторію WordPress.org або комерційного розповсюдження, ваше використання Hooks API безпосередньо визначає якість коду та рейтинги сумісності.
Найкращі практики для хуків виробничого рівня:
Завжди перевіряйте DOING_AUTOSAVE всередині колбеків save_post, щоб уникнути виконання ресурсомісткої логіки під час автозбережень.
Перевіряйте nonce та права доступу всередині будь-якого колбека хука, що обробляє дані, надіслані користувачем. Ніколи не вважайте, що сам хук забезпечує безпеку.
Використовуйте current_action(), щоб визначити, який саме хук запустив ваш колбек, коли одна функція зареєстрована для кількох хуків.
Додавайте простір імен до назв власних хуків, щоб уникнути колізій: my_plugin_event_name, а не event_name.
Версіонуйте свої хуки в документації, щоб розробники знали, коли хук був введений і коли він може бути застарілим.
Для команд, що розгортають WordPress на інфраструктурі з VPS Control Panels, підтримка тестових середовищ, що відображають продакшн, є необхідною для безпечного тестування взаємодій хуків перед розгортанням.
Захист вашої інсталяції WordPress разом із власними Actions
Власні хуки дій, що обробляють зовнішні дані, керують подіями автентифікації або взаємодіють із файловою системою, розширюють поверхню безпеки. Поєднуйте розробку хуків із належно захищеним хостинговим середовищем.
Переконайтеся, що ваша інсталяція WordPress використовує HTTPS — SSL Certificate є обов’язковим для будь-якого сайту, що обробляє автентифікацію користувачів або надсилання форм. Колбеки хуків, що спрацьовують на wp_login або user_register, обробляють конфіденційні дані по мережі; без TLS ці дані є відкритими незалежно від того, наскільки добре написаний ваш PHP-код.
Крім того, якщо ваш плагін використовує wp_mail() всередині колбеків дій (поширений патерн для сповіщень), конфігурація пошти вашого сервера та його репутація безпосередньо впливають на доставлюваність. Розгляньте спеціалізоване рішення Email Hosting з належними записами SPF, DKIM та DMARC замість покладання на серверний sendmail.
Матриця технічних рішень і ключові висновки
Використовуйте цей контрольний список при реалізації WordPress Actions у будь-якому проекті:
Реєстрація хуків:
Явно встановлюйте $accepted_args щоразу, коли хук передає більше одного аргументу
Використовуйте значення пріоритетів обдумано — документуйте, чому обрано нестандартні пріоритети
Реєструйте хуки всередині конструкторів класів або спеціальних методів register_hooks(), а не в глобальній області видимості файлу плагіна
Обмежуйте реєстрацію хуків контекстом, де вони потрібні (адмінка, фронтенд, REST API)
Реалізація колбеків:
Завжди перевіряйте DOING_AUTOSAVE, DOING_CRON та wp_is_json_request() там, де це доречно
Перевіряйте nonce за допомогою check_admin_referer() або check_ajax_referer() перед обробкою будь-якого введення користувача
Ніколи не покладайтеся на значення, що повертаються з do_action() — використовуйте фільтри, якщо вам потрібні дані назад
Використовуйте current_action(), коли один колбек обслуговує кілька хуків
Проектування власних хуків:
Додавайте простір імен до всіх власних назв хуків із префіксом вашого плагіна/теми
Документуйте кожен власний хук повним DocBlock над do_action()do_action() над do_action_ref_array(), якщо немає конкретної причиниПродуктивність і обслуговування:
- Профілюйте колбеки хуків за допомогою Query Monitor перед розгортанням у продакшн
- Уникайте запитів до бази даних всередині хуків, що спрацьовують при кожному запиті
- Використовуйте
remove_action()для очищення сторонніх хуків, що конфліктують із вашою реалізацією - Тестуйте взаємодії хуків у тестовому середовищі, що відображає продакшн-інфраструктуру
FAQ
У чому різниця між add_action() та add_filter() у WordPress?
add_action() реєструє колбек для виконання побічних ефектів у певній точці виконання — значення, що повертається, відкидається. add_filter() реєструє колбек для отримання, зміни та повернення значення. Використання одного замість іншого є функціональною помилкою: колбек фільтра, що не повертає значення, анулює відфільтровані дані.
Чому мій колбек add_action() не спрацьовує?
Найпоширеніші причини: (1) назва хука написана з помилкою, (2) add_action() викликається після того, як хук вже спрацював у поточному запиті, (3) $accepted_args занадто мале і колбек отримує неправильні дані, що спричиняє тиху помилку PHP, або (4) умовна перевірка всередині колбека перешкоджає виконанню. Використовуйте Query Monitor, щоб перевірити, чи спрацював хук і чи зареєстровано ваш колбек.
Чи можна використовувати add_action() всередині іншого колбека дії?
Так, і це поширений патерн. Наприклад, реєстрація хуків всередині plugins_loaded або init для забезпечення доступності залежностей. Однак внутрішній хук має спрацювати після зовнішнього, щоб реєстрація набула чинності.
Що насправді контролює параметр $priority?
Він контролює порядок, у якому виконуються кілька колбеків, зареєстрованих для одного хука. Менші числа спрацьовують першими. За замовчуванням 10. Допустимі значення включають від’ємні цілі числа. Коли два колбеки мають однаковий пріоритет, вони виконуються в порядку їх реєстрації через add_action().
Як безпечно видалити дію, додану стороннім плагіном?
Підключіть виклик remove_action() до дії, що спрацьовує після завантаження плагіна — зазвичай plugins_loaded з високим пріоритетом або after_setup_theme. Ви повинні точно збігти назву хука, посилання на колбек і пріоритет, використані в оригінальному виклику add_action(). Для методів об’єктів вам потрібен доступ до того самого екземпляра об’єкта, який авторитетні плагіни надають через глобальну змінну або статичний метод get_instance().
