apply_filters_ref_array() │ WP 3.0.0
Функция apply_filters_ref_array() выполняет функции, связанные с определённым фильтром, и принимает аргументы в виде массива.
Возвращаемое значение
Смешанное. Отфильтрованное значение после применения всех связанных функций.
Использование
apply_filters_ref_array( $hook_name, $args );
- $hook_name (строка) (обязательный) — имя фильтра.
- $args (массив) (обязательный) — аргументы, переданные функциям, связанным с фильтром.
Примеры
Пример 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' );
Пример 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
Пример 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 (всё работает как должно)
$link = 'old val';
echo apply_filters_ref_array( 'my_filter', [ 'ASC', & $link ] ); // DESC
echo $link; // new val
// Вызов 2 (НЕ работает - Ошибка парсинга)
$link = 'old val';
echo apply_filters( 'my_filter', 'ASC', & $link );
// Ошибка парсинга: неожиданный '&', ожидалось ')'
// Вызов 3 (НЕ работает - Предупреждение)
$link = 'old val';
$create_link = & $link;
echo apply_filters( 'my_filter', 'ASC', $create_link ); // DESC
// Предупреждение: Параметр 2 для my_filter_func() ожидается по ссылке
echo $link; // old val
Как мы видим, из всех вызовов, только первый работает корректно, где используется текущая функция apply_filters_ref_array().
Пример 4: Передача объекта в фильтр по ссылке
Этот пример показывает, что не обязательно использовать apply_filters_ref_array() для передачи объекта (экземпляра класса), но вы можете использовать основную функцию apply_filters(), когда требуется передать текущий объект $this.
Обратите внимание, что в прикрепленной функции не нужно указывать ссылку (& - просто $class, а не & $class), потому что объекты в PHP всегда передаются по ссылке.
class A {
var $var = 'one';
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(). Эта функция идентична, но аргументы, передаваемые функциям, связанным с фильтром, передаются с помощью массива. - Глобальная переменная.
$wp_filter[]. Хранит все фильтры и действия. - Глобальна�� переменная.
$wp_filters[]. Считывает количество раз, когда каждый фильтр был вызван. - Глобальная переменная.
$wp_current_filter[]. Содержит список текущих фильтров с последним текущим.
Журнал изменений
С версии 3.0.0 добавлено в WordPress.
Код функции
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 ];
}
// Сначала выполняем все действия 'all'.
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;
}
Теперь у вас есть подробное объяснение функции apply_filters_ref_array() в WordPress, а также примеры её использования.