WordPress как на ладони
Прибыльная монетизация. Выгодно. Безопасно. Стабильно.

do_action()WP 1.2.0

Создает событие (возможность запустить php функции в нужный момент работы кода). Подключать php функцию к событию нужно с помощью add_action().

Смотрите также аналогичную функцию: do_action_ref_array().

ВАЖНО: Если не передать ни один параметр в хук, то функция хука все равно получит один параметр со значением '' (пустая строка).

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

do_action( 'action_name' ); // выведет> string(0) ""

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

При вызове do_action, если переданный $arg является массивом с одним объектом, то вместо него будет передан именно этот объект, а не массив. Однако, если единственный элемент массива не является объектом, такой подмены не произойдет.

Пример:

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, но функция обратного вызова получила только класс stdclass, а не массив!

Кроме событий в WP также есть фильтры - apply_filters(). Принцип работы у них такой же - создаем фильтр и прикрепляем к нему php функцию которая сработает во время работы фильтра.

Разница между фильтрами и событиями в том, что фильтр получает какие-то данные и должен вернуть эти данные после их обработки, т.е. он фильтрует (изменяет) данные, а событие только лишь запускает прикрепленные к нему функции в нужный момент, передав в них какие-либо параметры.

Основа для: wp_footer(), wp_head()
1 раз — 0.00007 сек (очень быстро) | 50000 раз — 0.03 сек (скорость света)

Хуков нет.

Возвращает

null. Ничего не возвращает.

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

do_action( $tag, $arg_a, $arg_b, ... );
$tag(строка) (обязательный)
Название создаваемого хука.
$arg_a(строка/массив/число/объект/логический)
Значение аргумента, который будет передан.
По умолчанию: аргумент не существует
$arg_b(строка/массив/число/объект/логический)
Значение еще одного аргумента...
По умолчанию: аргумент не существует
$arg_с(строка/массив/число/объект/логический)
Функции можно передавать бесконечно много аргументов...

Примеры

0

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

Эту функцию можно использовать в плагинах, темах и т.д., когда нужно внедрится в процесс выполнения кода, откуда-нибудь из другого места. Например, "зацепку" (хук) (do_action) мы установили в плагине, а "цепляться" за нее будем из файла functions.php в тот момент, когда будет срабатывать наша "зацепка".

Допустим, мы использовали такой код в плагине:

<?php
// Определяем аргументы для хука action
$a = $defined; // $defined какая-нибудь динамическая логическая переменная
$b = 'А это значение второй переменной';

// Включаем хук. Здесь он будет выполняться
do_action( 'my_hook', $a, $b );

Теперь мы может сделать какое-нибудь действие в момент срабатывания функции do_action и при этом описать наше действие можно, например, из файла functions.php, разместив в нем такой код:

function do_my_hook( $a, $b ){
	// если переданная переменная $a равна true,
	// то, например, удалим запись 10
	if( $a===true )
		wp_delete_post(10);
	// а тут просто выведем переменную на экран
	echo '<br />'.$b; // выведет значение второй переменной
}
// Регистрируем хук через
// add_action( $tag, $function_to_add, $priority, $accepted_args );
add_action( 'my_hook', 'do_my_hook', 10, 2 );

Действия отличаются от фильтров, тем что передаваемые действием данные, не возвращаются обратно в функцию и не используются там в дальнейшем, а всего-лишь передаются для использования в функции хука.

0

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

Где-то в (mu-)плагине, теме или ядре. Например, в файле functions.php:

/**
 * У вас может быть столько аргументов, сколько вы хотите,
 * но ваша функция обратного вызова и вызов add_action должны быть согласованы по количеству аргументов.
 * Примечание: `add_action` выше имеет 2, а 'i_am_hook' принимает 2.
 * Вы найдете подобные хуки действий во многих темах и плагинах и во многих местах @core.
 * @see: https://codex.wordpress.org/Plugin_API/Action_Reference
 */

/**
 * Определяем функцию обратного вызова
 * Внутри этой функции вы можете делать все, что вам вздумается.
 * с переменными, которые загружены в вызове do_action() выше.
 */
function who_is_hook( $a, $b ) {

	print_r( $a ); // `print_r` данные массива внутри 1-го аргумента

	echo $b; // выводим символ перевода строки и значение 2-го аргумента
}

// затем добавить его в хук действия, сопоставив определенное количество (2) аргументов в do_action
// см. [https://codex.wordpress.org/Function_Reference/add_action] в Кодексе

// add_action( $tag, $function_to_add, $priority, $accepted_args );
add_action( 'i_am_hook', 'who_is_hook', 10, 2 );

// Define the arguments for the action hook
$a = array(
	'eye patch'  => 'yes',
	'parrot'     => true,
	'wooden leg' => 1
);

$b = 'And Hook said: "I ate ice cream with Peter Pan."';

// Executes the action hook named 'i_am_hook'
do_action( 'i_am_hook', $a, $b );

Результат:

Array (
	['eye patch'] => 'yes'
	['parrot'] => true
	['wooden leg'] => 1
)
And hook said: "I ate ice cream with Peter Pan."

Заметки

  • Global. WP_Hook[]. $wp_filter Stores all of the filters and actions.
  • Global. int[]. $wp_actions Stores the number of times each action was triggered.
  • Global. Строка[]. $wp_current_filter Stores the list of current filters with the current one last.

Список изменений

С версии 1.2.0 Введена.
С версии 5.3.0 Formalized the existing and already documented ...$arg parameter by adding it to the function signature.

Код do_action() WP 6.1.1

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 ];
	}

	// Do 'all' actions first.
	if ( isset( $wp_filter['all'] ) ) {
		$wp_current_filter[] = $hook_name;
		$all_args            = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
		_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] ) ) {
		// Backward compatibility for PHP4-style passing of `array( &$this )` as action `$arg`.
		$arg[0] = $arg[0][0];
	}

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

	array_pop( $wp_current_filter );
}
8 комментариев
    Войти