apply_filters_ref_array()WP 3.0.0

Execute functions hooked on a specific filter hook, specifying arguments in an array.

No Hooks.

Return

Mixed. The filtered value after all hooked functions are applied to it.

Usage

apply_filters_ref_array( $hook_name, $args );
$hook_name(string) (required)
The name of the filter hook.
$args(array) (required)
The arguments supplied to the functions hooked to (hook_name).

Examples

0

#1 Parameter transfer demonstration

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

This is same as:

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

#2 Example of adding a function to a filter

// call the hook
$filtered = apply_filters_ref_array( 'my_filter', [ 10, 2, 3 ] ); //> 10

// now, let's attach the function
add_filter( 'my_filter', 'my_filter_func', 10, 3 ); // 3 - get 3 parameters

function my_filter_func( $var, $var2, $var3 ){
	return $var2 + $var3;
}

// let's call the hook again, but now the my_filter_func() function is attached to it
$filtered = apply_filters_ref_array( 'my_filter', array( 10, 2, 3 ) ); //> 5
0

#3 Passing variables by reference

In this example, we pass all the parameters in the array, and the first parameter will work as in a normal filter, i.e. the attached function should return it, but the filter itself will return only the first parameter of the array - it is the variable $orderby in this example.

Also, we pass a variable by reference in the second parameter and my_filter_func() get it by reference in the attached function. So if we change this variable inside the attached function, it will also change outside the function.

// attach the function to the filter
add_filter( 'my_filter', 'my_filter_func', 10, 2 );

function my_filter_func( $orderby, & $link ){

	// change the $link parameter by reference
	$link = 'new val';

	// change the $orderby parameter as for the usual filter
	return 'DESC';
}

Now let's try to call the filter in different ways:

Call 1 (everything works as it should)

Call apply_filters_ref_array() and specify a reference to the second parameter.

// Define the variable we want to pass by reference
$link = 'old val';

// call the filter
echo apply_filters_ref_array( 'my_filter', [ 'ASC', & $link ] ); // DESC

// check how the variable has changed by reference
echo $link; // new val

Call 2 (NOT working - Parse Error)

Try the same as above, but with apply_filters():

$link = 'old val';

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

Call 3 (NOT working - Warning)

Try to do the same as above, with apply_filters(), but pass a variable that itself is a reference to another variable:

$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

As we can see, of all the calls, only the first one worked correctly, where the current apply_filters_ref_array() function is used.

0

#4 Transferring an object to a filter by reference

This example shows that it is not necessary to use apply_filters_ref_array() to pass an object (class instance), but you can use the basic apply_filters() function when the current object $this need to be passed to the filter.

Note that the attached function does not need to specify a reference (& - just $class, not & $class) for the received parameter, because objects in PHP are always passed by reference.

class A {

	var $var = 'one';

	function __construct(){

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

	function filter_func( $orderby, $class ){

		// in this case it is not necessary to specify & for $class,
		// because objects are always passed by reference!

		// change the object
		$class->var = 'one';

		// change the $orderby parameter as for the usual filter
		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"
	}

}

// call the class
$class = new A();
$class->apply_filters_and_echo();

/* We get:
string(4) "DESC"
string(3) "one"
*/

Notes

  • See: 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. String[]. $wp_current_filter Stores the list of current filters with the current one last.

Changelog

Since 3.0.0 Introduced.

apply_filters_ref_array() code WP 6.4.3

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