Функция do_action() в WordPress: события, добавление функций, примеры

DO_ACTION() │ WP 1.2.0

Функция do_action() создаёт событие (или "хуку") для работы с функциями PHP. Чтобы ваша функция ср��ботала во время этого события, нужно добавить её с помощью add_action().

Также есть похожая функция: do_action_ref_array().

Важно

Если вы не передали параметры в хуку, функция сработает всё равно и получит один параметр со значением '' (пустая строка).

Пример:


add_action( 'action_name', function( $first ){
var_dump( $first );
} );

do_action( 'action_name' ); // string(0) ""

Не передавайте массив с единственным объектом

Когда вы вызываете do_action, если передаёте массив с единственным объектом, в функцию будет передан именно этот объект, а не массив. Если же в вашем массиве находится хоть что-то другое, то оно будет передано без изменений.

Пример:


function my_callback( $should_be_an_array ){
print_r( $should_be_an_array );
}

add_action( 'my_action', 'my_callback' );

do_action( 'my_action', array( new stdClass() ) );

/
stdClass Object()
/

do_action( 'my_action', array( 'array_item_thats_not_an_object') );

/
Array (
[0] => array_item_thats_not_an_object
)
/

Обратите внимание, что в первом случае мы передали массив с объектом stdClass, но в функцию попал только этот объект, а не массив!

Не используйте переменную в имени хука

Пример неправильного использования:


// Не делайте так!
do_action( $some_var );
do_action( SOME_CONSTANT );
do_action( self::CONSTANT );

Проблема в том, что хуки служат для расширения возможностей других модулей. Другой модуль не должен знать о переменных (состоянии) вашего модуля. Если другое расширение (плагин) использует ваш хук, оно будет зависеть от значения вашей переменной. Но переменная может измениться, и если вы её измените, это может привести к поломке функциональности модуля, использующего ваш хук.

Любое изменение названия хука должно быть обоснованным и значимым. На практике я никогда не встречал веские причины использовать переменную в названии хука. Однако такой код встречается — избегайте его!

Это также усложняет отладку и затрудняет автоматическую генерацию документации по коду и т.д.

В дополнение к хукам, в WordPress также есть фильтры — apply_filters(). Они работают аналогичным образом, лишь отличие в том, что фильтры передают значение в функцию PHP, это значение нужно обработать и вернуть.

Использование хуков

Функция do_action() используется в темах, плагинах и т.д., когда нужно "встряхнуть" процесс выполнения кода. Например, мы вызываем действие (do_action) из плагина, хотя это действие добав��ено в тему.

Предположим, что в плагине есть такой код:


// Аргументы, которые будут переданы функциям, подключённым к хуку.
$a = $defined; // Какая-то динамическая переменная
$b = 'Некоторая строка';

// Вызов действия (активация хука)
do_action( 'my_hook', $a, $b );

А в файле functions.php темы находится следующий код:


function do_my_hook( $a, $b ){
// Если переменная $a равна true,
// то, например, удалить пост с ID 10
if( $a === true ) {
wp_delete_post( 10 );
}

// Здесь просто выводим значение второй переменной
echo '
'.$b;

}

// Подключаем функцию к хуку
add_action( 'my_hook', 'do_my_hook', 10, 2 );

Пример использования

В этом примере также можно использовать несколько аргументов, но ваша функция обратного вызова и вызов add_action должны согласовываться по количеству аргументов.


function who_is_hook( $a, $b ) {
print_r( $a ); // выводим массив данных первого аргумента
echo $b; // выводим значение второго аргумента
}

// добавляем к действию, соблюдая совпадение числа аргументов
add_action( 'i_am_hook', 'who_is_hook', 10, 2 );

// Определяем аргументы для хука
$a = array(
'eye patch' => 'yes',
'parrot' => true,
'wooden leg' => 1
);

$b = 'И Хук сказал: "Я ел мороженое с Питером Пэном."';

// Выполнение хука с именем 'i_am_hook'
do_action( 'i_am_hook', $a, $b );

Результат

Array (
    ['eye patch'] => 'yes'
    ['parrot'] => true
    ['wooden leg'] => 1
)
И Хук сказал: "Я ел мороженое с Питером Пэном."

Важно знать

  • Глобальные: WP_Hook[]. $wp_filter хранит все фильтры и действия.
  • Глобальные: Int[]. $wp_actions хранит количество вызовов каждого действия.
  • Глобальные: String[]. $wp_current_filter хранит список текущих фильтров, последний из которых актуален.

Изменения

  • С версии 1.2.0 — функция была введена.
  • С версии 5.3.0 — параметр ...$arg был формализован и добавлен в сигнатуру функции.

Код do_action для WP 6.7.2


function do_action( $hook_name, ...$arg ) {
global $wp_filter, $wp_actions, $wp_current_filter;

if ( ! isset( $wp_actions[ $hook_name ] ) ) {
    $wp_actions[ $hook_name ] = 1;
} else {
    ++$wp_actions[ $hook_name ];
}

// Сначала выполняем все действия.
if ( isset( $wp_filter['all'] ) ) {
    $wp_current_filter[] = $hook_name;
    $all_args            = func_get_args();
    _wp_call_all_hook( $all_args );
}

if ( ! isset( $wp_filter[ $hook_name ] ) ) {
    if ( isset( $wp_filter['all'] ) ) {
        array_pop( $wp_current_filter );
    }
    return;
}

if ( ! isset( $wp_filter['all'] ) ) {
    $wp_current_filter[] = $hook_name;
}

if ( empty( $arg ) ) {
    $arg[] = '';
} elseif ( is_array( $arg[0] ) && 1 === count( $arg[0] ) && isset( $arg[0][0] ) && is_object( $arg[0][0] ) ) {
    $arg[0] = $arg[0][0];
}

$wp_filter[ $hook_name ]->do_action( $arg );

array_pop( $wp_current_filter );

}

Связанные функции

Действия (хуки):

  • add_action()
  • did_action()
  • do_action_ref_array()
  • doing_action()
  • has_action()
  • remove_action()
  • remove_all_actions()

Хуки (действия, фильтры):

  • add_filter()
  • apply_filters()
  • apply_filters_ref_array()
  • current_filter()
  • doing_filter()
  • has_filter()
  • remove_all_filters()
  • remove_filter()

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *