过滤钩和动作钩之间的区别?


51

最近,我一直在更深入地研究插件API,我想知道action和filter挂钩之间的真正区别什么。它们都是接收数据作为参数的事件,它们似乎都可以做相同的事情。

显然,我看到在操作发生时会调用操作,在处理数据时会调用过滤器,但这似乎只是语义上的区别。

除了语义及其用途之外,它们之间还有什么真正的区别?

Answers:


58

@Sruly

您已经回答了您自己的问题,但是我会详细说明。

动作钩

当WordPress核心或某些插件或主题使您有机会在特定点插入代码并执行以下一项或多项操作时,可以使用操作挂钩。

  1. 使用echo注入一些HTML或其他内容到响应缓冲区,
  2. 修改一个或多个变量的全局变量状态,和/或
  3. 修改传递给钩子函数的参数(假设钩子由do_action_ref_array()而不是调用,do_action()因为钩子不支持按引用传递变量。)

滤钩

过滤器挂钩的行为与操作挂钩非常相似,但它们的预期用途是接收值并可能返回该值的修改版本。过滤器挂钩也可以像动作挂钩一样使用,即修改全局变量或生成一些HTML,前提是调用挂钩时需要执行此操作。关于过滤器挂钩非常重要的一件事,您无需担心操作挂钩,这是使用过滤器挂钩的人必须返回它传递的第一个参数(的修改版本)。新手常见的错误是忘记返回该值!

使用附加参数在过滤器挂钩中提供上下文

顺便说一句,我觉得过滤钩子是在早期版本的WordPress的步履蹒跚,因为他们将接受只有一个参数; 也就是说,他们将获得一个要修改的值,但没有第二个或第三个参数可以提供任何上下文。但是,最近,积极的是,似乎WordPress核心团队(对我来说)很高兴地向Filter Hooks添加了额外的参数,以便您可以发现更多上下文。posts_where钩子就是一个很好的例子。我相信有几个版本支持它仅接受一个参数作为当前查询的“ where”类SQL,但是现在它接受where子句WP_Query调用该钩子的类的当前实例的引用。

那么真正的区别是什么?

实际上,筛选器挂钩几乎是动作挂钩的超集。前者可以执行后者所能做的任何事情,并且更多一点,尽管开发人员没有责任使用Action Hook返回值,而后者是他或她使用Filter Hook所做的。

提供指导和电报意图

但这可能并不重要。我认为重要的是,通过选择使用Action Hook和Filter Hook的开发人员,反之亦然,他们在传达自己的意图,从而可能正在使用该Hook的主题或插件开发人员提供指导。本质上,他们说的是“我要打电话给您,做您需要做的一切” “我要将该值传递给您以进行修改,但请确保将其传递回来。”

因此,最终我认为,选择钩子类型所提供的指导是区别背后的真正价值。IMO,无论如何。

希望这可以帮助!


在我看来,您可能只需要对所有内容使用过滤器,因为在PHP中返回变量是可选的。谁知道WordPress开发人员为什么选择使用两个单独的术语?纯粹是出于语义原因吗?从技术上讲,我看不到它的必要...
TheStoryCoder 2015年

2
@TheStoryCoder “这纯粹是出于语义原因吗?” 似乎正是我的答案在五(5)年前所解释的...?
MikeSchinkel 2015年

11

如果您查看add_action()核心功能的源代码,那么它只是add_filter()功能的包装...

而且,如果您查看do_action()核心函数,它与核心函数非常相似,但apply_filters()有一个非常关键的区别:它不返回值。

那么这是什么意思?操作类似于过滤器,除了操作不返回值之外,因此您无法修改数据。它表明通过简单地复制过滤器机制而不返回值来创建WordPress的动作机制很简单。基本上,您可以使用一个动作来执行所有功能,而无需修改某些值即可。


5

简单来说。

动作 是那些执行输出的PHP函数。

过滤器 是那些返回输出的PHP函数。

更新:我们可以扩展使用操作和过滤器的任何插件,而无需修改其中的代码。通过在我们自己的主题或插件中添加过滤器和操作。


如何使用?

行动:

查看主题functions.php文件中的以下简单示例。

  1. 示例一:(简单的PHP示例)
功能测试() {
     回显“输出”;
}

测试();

上面的程序打印输出:

输出量

[注意:这里的test()只是调用函数。并执行回调函数“ test”。]


  1. 示例二:(简单使用Action)
函数test1(){
     回显“输出”;
}
add_action('test','test1');

do_action('test');

上面的程序打印输出:

输出量

[注意:这里的do_action('test')工作类似于调用函数。并执行回调函数“ test1”。]


  1. 示例三:(另一种使用动作)
函数test2(){
     回显“测试2”;
}
add_action('test','test2',1);

函数test1(){
     回显“测试1”;
}
add_action('test','test1',2);

do_action('test');

上面的程序打印输出:

测试2测试1

[注意:这里的do_action('test')工作类似于调用函数。并按优先级执行回调函数。

回调函数'test1'具有优先级2,而'test2'具有优先级1。]

如果更改优先级,例如优先级为1的“ test1”和优先级为2的“ test2”,则输出将为:

测试1测试2

  1. 示例四:(第三方支持) 在下面添加以下代码functions.php
函数test1(){
     do_action('test_before');
     回显“测试1”;
     do_action('test_after');
}
add_action('test','test1');

do_action('test');

上面的程序打印输出:

测试1

现在,创建示例插件以检查其对第三方开发人员的工作方式。

  1. /wp-content/plugins/目录中创建文件夹“ simple” 。
  2. 创建名为“ simple.php”的文件并添加以下代码。
/ *
*插件名称:简单插件
* /
函数test_callback_function(){
     回显“来自插件”;
}
add_action('test','test_callback_function');

现在,从WordPress管理控制台激活我们的Simple插件

转到菜单插件并激活它。

在激活上面程序的插件后,输出输出:

测试1来自插件

[注意:如果我们将插件操作的优先级从1增至9,则其输出结果如下:

从pluginTest 1

因为,WordPress考虑了10 priority by default所有已添加的操作。]

筛选器

检查以下示例:

简单的PHP示例:

$ data = array('一个','两个');
print_r($ data);

上面的程序打印输出:

数组([0] => 1 [1] => 2)
  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');
});

上面的程序打印输出:

数组([0] =>三个[1] =>四个)

在这里,我们添加了过滤器my_filter_name并更改了现有的输出array( 'one', 'two' )array( 'three', 'four' )而没有更改主题/插件文件。



感谢@maheshwaghmare这样的简单技巧。请写“过滤器”太多
阿迪

“很快”到底是什么意思?
拉普蒂

@Rapti对不起,谢谢您。今晚,我将添加与过滤器有关的答案。将来,我将创建有关Hooks(Actions&Filters)的描述性文章。
maheshwaghmare

@maheshwaghmare拖延了多少?:P

好解释,我现在有了更好的理解
budiantoip
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.