apply_filters_ref_array()WP 3.0.0

Выполняет функции прикрепленные к указанному хуку (фильтру). Параметры передаются в массиве. Позволяет передать параметр по ссылке.

Эта функция отличается от apply_filters() тем, что параметры в прикрепленную функцию передаются в массиве. Это позволяет передать некоторые из параметров по ссылке.

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

При передаче аргументов, не забудьте убедиться, что они находятся в нужном порядке.

Хуков нет.

Возвращает

Разное. Отфильтрованное значение, после того, как все прикрепленные к хуку функции обработают это значение.

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

apply_filters_ref_array( $tag, $args );
$tag(строка) (обязательный)
Название фильтра (хука).
$args(массив) (обязательный)

Параметры, которые будут переданы в прикрепленную функцию. Все параметры должны быть переданы как элементы одного массива. А прикрепленная функция получит каждый элемент этого массива, как отдельный параметр:

// прикрепляемая функция
function my_filter_func( $var, $var2 ){
	// $var - 1
	// $var2 - 2

	return $var;
}

// 2 - означает что функция получит два параметра
add_filter('my_filter', 'my_filter_func', 10, 2 );

// вызываем фильтр
$one = apply_filters_ref_array('my_filter', [ 1, 2 ] );

Примеры

0

#1 Демонстрация передачи параметров

$args = array( 'arg_1', true, 'foo', 'arg_4' );
$arg_1 = apply_filters_ref_array( 'my_filter', $args );

Эта запись равносильна такой:

$arg_1 = apply_filters( 'my_filter', 'arg_1', true, 'foo', 'arg_4' );
0

#2 Пример добавления функции к фильтру

// вызовем хук
$filtered = apply_filters_ref_array( 'my_filter', [ 10, 2, 3 ] ); //> 10

// теперь, прикрепим функцию
add_filter( 'my_filter', 'my_filter_func', 10, 3 ); // 3 - получит 3 параметра
function my_filter_func( $var, $var2, $var3 ){
	return $var2 + $var3;
}

// вызовем хук еще рас, но теперь к нему прикреплена функция my_filter_func()
$filtered = apply_filters_ref_array( 'my_filter', array( 10, 2, 3 ) ); //> 5
0

#3 Передача переменных по ссылке

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

Также, во втором параметре мы передаем переменную по ссылке и в прикрепленной функции my_filter_func() получаем её по ссылке. Таким образом при изменение этой переменной внутри прикрепленной функции, она также изменится и за пределами функции.

// прикрепим функцию к фильтру
add_filter( 'my_filter', 'my_filter_func', 10, 2 );

function my_filter_func( $orderby, & $link ){

	// изменим параметр $link по ссылке
	$link = 'new val';

	// изменим параметр $orderby как для обычного фильтра
	return 'DESC';
}

Теперь попробуем вызвать фильтр разными способами:

Вызов 1 (все работает как надо)

Вызываем через apply_filters_ref_array() и указываем ссылку на второй параметр.

// Определим переменную, которую хотим передать по ссылке
$link = 'old val';

// вызываем фильтр
echo apply_filters_ref_array( 'my_filter', [ 'ASC', & $link ] ); // DESC

// проверим как изменилась переменная по ссылке
echo $link; // new val

Вызов 2 (Parse Error)

Пробуем сделать тоже самое что и выше, только через apply_filters():

$link = 'old val';

// Parse Error: syntax error, unexpected '&', expecting ')'
echo apply_filters( 'my_filter', 'ASC', & $link );

Вызов 3 (Warning)

Пробуем сделать тоже самое что и выше, через apply_filters(), только передаем переменную которая сама является ссылкой на другую переменную:

$link = 'old val';

$create_link = & $link;

echo apply_filters( 'my_filter', 'ASC', $create_link ); // DESC

// Warning: Parameter 2 to my_filter_func() expected to be a reference

echo $link; // old val

Как мы видим из всех вызовов правильно отработал только первый, где используется текущая функция apply_filters_ref_array().

0

#4 Передача объекта в фильтр по ссылке

Этот пример показывает, что для передачи класса не обязательно использовать apply_filters_ref_array(), а можно использовать базовую функцию apply_filters() когда в фильтр нужно передать текущий объект $this.

Обратите внимание, что в прикрепляемой функции нет необходимости указывать ссылку (& - просто $class, а не & $class) для получаемого параметра, потому что объекты в PHP всегда передается по ссылке.

class A {

	var $var = 'один';

	function __construct(){

		add_filter( 'my_filter', [ $this, 'filter_func' ], 10, 2 );
	}

	function filter_func( $orderby, $class ){

		// в этом случае не обязательно указывать & для $class,
		// потому что объекты всегда передаются по ссылке!

		// изменим объект
		$class->var = 'one';

		// изменим параметр $orderby как для обычного фильтра
		return 'DESC';
	}

	function apply_filters_and_echo(){

		$orderby = apply_filters( 'my_filter', 'ASC', $this );

		var_dump( $orderby );   // string(4) "DESC"
		var_dump( $this->var ); // string(3) "one"
	}

}

// вызова класса
$class = new A();
$class->apply_filters_and_echo();

/* Получим:
string(4) "DESC"
string(3) "one"
*/

Заметки

  • Смотрите: apply_filters() This function is identical, but the arguments passed to the
    functions hooked to (hook_name) supplied using an array.
  • Global. WP_Hook[]. $wp_filter Stores all of the filters and actions.
  • Global. int[]. $wp_filters Stores the number of times each filter was triggered.
  • Global. Строка[]. $wp_current_filter Stores the list of current filters with the current one last.

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

С версии 3.0.0 Введена.

Код apply_filters_ref_array() WP 6.7.1

function apply_filters_ref_array( $hook_name, $args ) {
	global $wp_filter, $wp_filters, $wp_current_filter;

	if ( ! isset( $wp_filters[ $hook_name ] ) ) {
		$wp_filters[ $hook_name ] = 1;
	} else {
		++$wp_filters[ $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 $args[0];
	}

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

	$filtered = $wp_filter[ $hook_name ]->apply_filters( $args[0], $args );

	array_pop( $wp_current_filter );

	return $filtered;
}