Функция do_action_ref_array() в WordPress: описание, примеры, использование

## DO_ACTION_REF_ARRAY() │ WP 2.1.0

Функция do_action_ref_array() создает действие (хука), к которому можно прикреплять функции на PHP. Аргументы передаются в виде массива.

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

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

### Возвращаемое значение

Функция ничего не возвращает (null).

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

```php
do_action_ref_array( $hook_name, $args );
  • $hook_name (string) (обязательный) — имя действия, которое нужно выполнить.
  • $args (array) (обязательный) — параметры, передаваемые функциям, связанным с указанным хуком $hook_name.

Примеры

Пример 1: Разница с do_action()

do_action( 'my_action', 'arg_1', true, 'foo', 'arg_4' );

// Это то же самое, что и
$args = [ 'arg_1', true, 'foo', 'arg_4' ];
do_action_ref_array( 'my_action', $args );

Пример 2: Создание хука с передачей параметра по ссылке

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

// Добавляем функцию обратного вызова к хуку
add_action( 'myhook', 'myhook_func' );

function myhook_func( & $num ) {
    $num = 2; // Изменяем переменную по ссылке
}

$num = 1;

// Вызов хука
do_action_ref_array( 'myhook', array( & $num ) );

echo $num; //> 2

Пример 3: Создание хука с передачей объекта по ссылке

Если массив содержит объект, его не нужно передавать по ссылке, так как объект всегда передается по ссылке:

// Добавляем функцию обратного вызова к хуку
add_action( 'my_action', 'my_callback' );

function my_callback( $my_object ) {
    $my_object->prop += 2; // добавляем 2
}

// Создаем объект
$my_object = new stdClass();
$my_object->prop = 1;

// Запускаем хук
do_action_ref_array( 'my_action', array( $my_object ) );

// Проверяем, что объект изменился
var_dump( $my_object->prop ); // int(3)

// Можно также использовать do_action вместо do_action_ref_array
do_action( 'my_action', $my_object );

// Проверяем, что объект изменился
var_dump( $my_object->prop ); //> int(5)

Пример 4: Передача нескольких параметров

add_action( 'my_action', 'my_callback', 10, 4 );

function my_callback( $arg1 = '', $arg2 = '', $arg3 = '', $arg4 = '' ) {
    print_r( func_get_args() );
}

$args = [ 'one', 'two', 'three', 'four' ];

do_action( 'my_action', $args[0], $args[1] );

/*
Array
(
    [0] => one
    [1] => two
)
*/

do_action_ref_array( 'my_action', $args );

/*
Array
(
    [0] => one
    [1] => two
    [2] => three
    [3] => four
)
*/

// С PHP 5.6 можно сделать следующее:
do_action( 'my_action', ...$args );

/*
Array
(
    [0] => one
    [1] => two
    [2] => three
    [3] => four
)
*/

Примечания

  • Функция do_action() аналогична do_action_ref_array(), но аргументы передаются непосредственно, а не в виде массива.
  • Глобальные переменные:
    • $wp_filter[] хранит все фильтры и действия.
    • $wp_actions[] хранит количество вызовов каждого действия.
    • $wp_current_filter[] хранит список текущих фильтров, где последний — текущий.

Журнал изменений

  • Появилась в версии 2.1.0.

Код функции do_action_ref_array

function do_action_ref_array( $hook_name, $args ) {
    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;
    }

    $wp_filter[ $hook_name ]->do_action( $args );
    array_pop( $wp_current_filter );
}

Leave a Reply

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