В чем разница между фильтрами и хуками действий?

29 авг. 2010 г., 15:27:31
Просмотры: 38.6K
Голосов: 63

В последнее время я более подробно изучаю API плагинов, и меня интересует какие реальные различия существуют между хуками действий (action hooks) и фильтрами (filter hooks). Оба они являются событиями, которые получают данные в качестве параметра, и, похоже, они оба могут выполнять одни и те же функции.

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

Помимо семантики и их предназначения, какие реальные различия существуют между ними?

0
Все ответы на вопрос 4
3
68

Привет @Sruly:

Ты практически сам ответил на свой вопрос, но я немного разверну ответ.

Хуки действий (Action Hooks)

Хуки действий предназначены для случаев, когда WordPress или какой-то плагин/тема дают вам возможность вставить свой код в определённой точке и выполнить одно или несколько из следующих действий:

  1. Использовать echo для вставки HTML или другого контента в буфер вывода,
  2. Изменять глобальные переменные (одну или несколько), и/или
  3. Модифицировать параметры, переданные в функцию хука (при условии, что хук был вызван через do_action_ref_array(), а не do_action(), так как последний не поддерживает передачу переменных по ссылке).

Хуки фильтров (Filter Hooks)

Хуки фильтров ведут себя очень похоже на хуки действий, но их основное назначение — получить значение и потенциально вернуть его модифицированную версию. Хук фильтра также может использоваться как хук действия — например, для изменения глобальной переменной или генерации HTML, если это требуется при вызове хука. Очень важный момент, который отличает хуки фильтров от хуков действий: функция, использующая хук фильтра, обязана вернуть (модифицированную версию) первого переданного параметра. Частая ошибка новичков — забыть вернуть это значение!

Использование дополнительных параметров для контекста в хуках фильтров

К слову, мне казалось, что хуки фильтров в ранних версиях WordPress были ограничены, так как получали только один параметр — значение для модификации, но без второго или третьего параметра, который мог бы дать контекст. Однако в последнее время команда WordPress начала добавлять дополнительные параметры в хуки фильтров, что очень радует. Хороший пример — хук posts_where: раньше он принимал только один параметр (SQL-условие "WHERE" текущего запроса), но теперь он принимает и условие WHERE, и ссылку на текущий экземпляр класса WP_Query, который вызывает хук.

Так в чём же реальная разница?

По сути, хуки фильтров — это расширенная версия хуков действий. Они могут делать всё то же самое и даже немного больше, хотя разработчик не обязан возвращать значение в хуке действий, как это требуется в хуке фильтров.

Передача намерений и указание цели

Но, вероятно, важно не это. Важно то, что, выбирая между хуком действия и хуком фильтра, разработчик передаёт своё намерение и тем самым даёт подсказку разработчику темы или плагина, который будет использовать этот хук. По сути, он говорит либо "Я вызову тебя, делай что нужно", ЛИБО "Я передам тебе это значение для модификации, но не забудь вернуть его обратно".

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

Надеюсь, это поможет!

29 авг. 2010 г. 16:57:19
Комментарии

Мне кажется, можно было бы использовать только фильтры для всего, так как возврат переменной в PHP необязателен. Кто-нибудь знает, почему разработчики WordPress выбрали разделение на два разных термина? Это чисто семантические причины? Технически я не вижу в этом необходимости...

TheStoryCoder TheStoryCoder
10 июн. 2015 г. 10:27:23

@TheStoryCoder "Это чисто семантические причины?" Похоже, что именно это мой ответ и объяснил пять (5) лет назад...?

MikeSchinkel MikeSchinkel
14 июн. 2015 г. 02:13:39

Я очень рад, что нашел и этот вопрос, и этот ответ. Уверен, большинство проголосовавших согласятся со мной в том, что по сути это одно и то же, а объяснение нюансов в данном ответе дает удовлетворительное разъяснение.

ecv ecv
18 мар. 2024 г. 00:46:03
0
14

Если посмотреть исходный код основной функции add_action(), то это просто обёртка для функции add_filter()...

А если изучить функцию do_action(), то она очень похожа на основную функцию apply_filters(), с одним ключевым отличием: она не возвращает значение.

Что это значит? Действия (actions) похожи на фильтры (filters), за исключением того, что действие не возвращает значение, поэтому вы не можете модифицировать данные. Это показывает, что механизм действий в WordPress был создан просто копированием механизма фильтров, но без возврата значения. По сути, всё что вы можете сделать с действием — это просто выполнить функцию без модификации какого-либо значения.

29 июн. 2013 г. 21:41:50
7

Простыми словами.

Действия (Actions) — это PHP-функции, которые выполняют вывод.

Фильтры (Filters) — это PHP-функции, которые возвращают вывод.

Обновлено: Мы можем расширить любой плагин, который использует действия и фильтры, без изменения его кода. Добавляя фильтры и действия в нашей собственной теме или плагине.


Как использовать?

Действия (Actions):

Проверьте простые примеры ниже в файле functions.php вашей темы.

  1. Пример первый: (Простой пример на PHP)
function test() {
     echo "Вывод";
}

test();

Вывод программы выше:

Вывод

[ПРИМЕЧАНИЕ: Здесь test() просто вызывает функцию и выполняет callback-функцию 'test'.]


  1. Пример второй: (Простое использование действия)
function test1() {
     echo "Вывод";
}
add_action( 'test', 'test1' );

do_action( 'test' );

Вывод программы выше:

Вывод

[ПРИМЕЧАНИЕ: Здесь do_action('test') работает как вызов функции и выполняет callback-функцию 'test1'.]


  1. Пример третий: (Другое использование действий)
function test2() {
     echo "Тест 2";
}
add_action( 'test', 'test2', 1 );

function test1() {
     echo "Тест 1";
}
add_action( 'test', 'test1', 2 );

do_action( 'test' );

Вывод программы выше:

Тест 2Тест 1

[ПРИМЕЧАНИЕ: Здесь do_action('test') работает как вызов функции и выполняет callback-функции в соответствии с их приоритетами.

Callback-функция 'test1' имеет приоритет 2, а 'test2' — приоритет 1.]

Если изменить приоритеты, например, 'test1' с приоритетом 1 и 'test2' с приоритетом 2, то вывод будет:

Тест 1Тест 2

  1. Пример четвертый: (Поддержка сторонних разработчиков) Добавьте следующий код в functions.php
function test1() {
     do_action( 'test_before' );
     echo "Тест 1";
     do_action( 'test_after' );
}
add_action( 'test', 'test1' );

do_action( 'test' );

Вывод программы выше:

Тест 1

Теперь создадим простой плагин, чтобы проверить, как это работает для сторонних разработчиков.

  1. Создайте папку 'simple' в директории /wp-content/plugins/.
  2. Создайте файл с именем 'simple.php' и добавьте следующий код.
/*
* Plugin Name: Simple Plugin
*/
function test_callback_function() {
     echo "Из плагина";
}
add_action( 'test', 'test_callback_function' );

Теперь активируйте наш Simple plugin из админ-панели WordPress.

Перейдите в меню "Плагины" и активируйте его.

После активации плагина вывод программы будет:

Тест 1Из плагина

[ПРИМЕЧАНИЕ: Если мы установим приоритет для действия нашего плагина от 1 до 9, то вывод будет таким:

Из плагинаТест 1

Потому что WordPress по умолчанию использует приоритет 10 для всех добавленных действий.]

Фильтры (Filters)

Проверьте следующие примеры:

Простой пример на PHP:

$data = array( 'one', 'two' );
print_r( $data );

Вывод программы выше:

Array ( [0] => one [1] => two )
  1. Пример первый: (Простое использование фильтра)
$data = apply_filters( 'my_filter_name', array( 'one', 'two' ) );
print_r( $data );

add_filter( 'my_filter_name', function( $old_data ) {
     return array( 'three', 'four' );
});

Вывод программы выше:

Array ( [0] => three [1] => four )

Здесь мы добавили фильтр my_filter_name и изменили существующий вывод array( 'one', 'two' ) на array( 'three', 'four' ) без изменения файлов темы/плагина.


3 февр. 2017 г. 17:37:31
Комментарии

Спасибо @maheshwaghmare за такой простой трюк. Пожалуйста, напиши также про 'Фильтры'

Adi Adi
22 февр. 2017 г. 12:59:19

Что именно ты подразумеваешь под "скоро"?

Rapti Rapti
4 апр. 2017 г. 16:15:39

@Rapti Извини за задержку. Сегодня вечером я добавлю ответ про фильтры. В будущем я напишу развернутую статью про хуки (Действия и Фильтры).

maheshwaghmare maheshwaghmare
4 апр. 2017 г. 17:02:42

@maheshwaghmare много прокрастинируешь? :P

User User
4 мая 2017 г. 04:37:09

Хорошее объяснение, теперь мне стало понятнее

Budianto IP Budianto IP
11 февр. 2018 г. 20:01:39

Почему бы не вызывать методы напрямую и не фильтровать данные там, где это нужно? В чем реальное назначение методов do_action, add_action и apply_filters?

f_i f_i
18 мар. 2018 г. 16:55:01

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

maheshwaghmare maheshwaghmare
18 мар. 2018 г. 16:56:46
Показать остальные 2 комментариев
0

Основное различие между действием (action) и фильтром (filter) можно описать следующим образом:

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

Или иначе:

  • Действие прерывает поток выполнения кода, чтобы что-то сделать, а затем возвращается к обычному потоку, ничего не изменяя;
  • Фильтр используется для изменения чего-то определённым образом, чтобы это изменение затем использовалось в дальнейшем коде.

Что-то, о чём идёт речь, — это список параметров, передаваемых через определение хука.

Из официальной документации WordPress

16 нояб. 2020 г. 12:36:52