15%

Збережіть 15% на всі хостинг-послуги

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код:

Skills
Почати
22.10.2024

Дії 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.

Потік виконання виглядає так:

  1. Ядро WordPress (або плагін/тема) викликає do_action( 'hook_name', ...$args ).
  2. WordPress визначає всі колбеки, зареєстровані для hook_name з $wp_filter.
  3. Колбеки сортуються за значенням $priority (за зростанням — менші числа спрацьовують першими).
  4. Кожен колбек викликається з переданими аргументами.
  5. Значення, що повертаються, мовчки ігноруються.
  6. Виконання продовжується у вихідному коді після повернення 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().

15%

Збережіть 15% на всі хостинг-послуги

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код:

Skills
Почати