WordPress开发:add_filter和apply_filters过滤器钩子

1 操作环境

操作系统信息:

master@ubuntu:~$ lsb_release -a
No LSB modules are available.
Distributor ID:    Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:    18.04
Codename:    bionic

WordPress 信息:

主程序版本:WordPress 5.3.2
主题及版本:Twenty Sixteen(版本:2.0, 由WordPress团队开发)

2 本文概要

本文主要介绍 WprdPress 平台中提供的两个过滤器钩子:

  • add_filter
  • apply_filters

简单地说,add_filter 是添加过滤器钩子的函数(过滤器添加钩子),而 apply_filters 是应用过滤器钩子的函数(过滤器应用钩子)。

为了辅助理解,本文中还会展示一些关于这两个过滤器钩子的使用样例。

3 格式说明

  • 在没有特殊说明的情况下,下文中出现的 “WordPress” 和 “WP” 所代表的是相同的含义。
  • 在“应用实例”部分所出现的代码中,凡是我自己定义的函数和变量等,一般都会以 zkf_ 作为其前缀;没有使用 zkf_ 作为前缀的函数或者变量等,一般情况下都是 WordPress 平台或者 PHP 提供的。

4 过滤器钩子与动作钩子

WP 的过滤器钩子和动作钩子最大的区别就是,动作钩子仅执行挂载到该钩子上的函数,不产生返回值,而过滤器钩子执行完挂载到该钩子上的函数之后,还会产生一个返回值。

WP 平台中提供过滤器钩子的主要目的就是允许插件在运行过程中修改各种类型的内部数据,从而使插件能够完成更加多样的功能。插件可以将回调函数挂载到过滤器钩子上,当这个过滤器被应用时,它会按照所挂载函数的优先级或者函数的添加顺序执行挂载到它上面的全部函数,实现对数据的修改并返回一个新的数据(过滤后的数据)。

5 add_filter

5.1 格式

add_filter( string $tag, callable $function_to_add, int $priority = 10, int $accepted_args = 1 )

5.2 作用

“Hook a function or method to a specific filter action.”

即:“挂载一个函数或者方法到一个特定的过滤器动作上。”

5.3 参数解析

  • $tag
    (string 类型) (必须参数) 用于挂载回调函数 $function_to_add 的过滤器钩子的名称。
  • $function_to_add
    (callable 类型) (必须参数) 过滤器钩子被激活后需要运行的回调函数。
  • $priority
    (int 类型) (可选参数) 用于指定过滤器中回调函数的运行顺序,即优先级。数字越小就会越早被执行,若不同的回调函数有相同的优先级,则按照它们被添加到过滤器中的先后顺序顺次执行。优先级的默认值为 10.
  • $accepted_args
    (int 类型) (可选参数) 回调函数接收的参数的数量。默认值为 1.

Note: 为了加快系统的运行速度,无论回调函数是否有效,add_filter() 的返回值都将为 true. 正因如此,我们无法通过 add_filter() 的返回值判断回调函数的执行结果,这一点要格外注意。

5.4 使用样例

下面这两个样例将展示一个回调函数是如何挂载(绑定)到一个过滤器钩子上的。

function example_callback( $example ) {
/*
$example 参数先是被传递给回调函数 example_callback
之后,(或许被)修改后再将参数 $example 返回
*/
    return $example;
}

//将回调函数 example_callback 挂载到 过滤器钩子 example_filter 上面
add_filter( 'example_filter', 'example_callback' );

Note: 被挂载的回调函数可以没有参数传入,也可以传入多个参数,具体传入多少参数,需要根据相应的 apply_filters() 确定。回调函数需要的参数的个数不能超过 apply_filters() 提供的参数的个数,具体要给回调函数多少个参数,需要在 apply_filters() 中使用 $accepted_args 参数指定,如果不指定 $accepted_args 参数,则默认可以传入的参数的个数为 1, 例如:

//唤起过滤器钩子
$value = apply_filters( 'hook', $value, $arg2, $arg3 );

//接收0个或1个参数
function example_callback() {
    ...
    return 'some value';
}
add_filter( 'hook', 'example_callback' );
//优先级默认为10, 接收的参数个数默认为1.

或者:

//接收2个参数
function example_callback( $value, $arg2 ) {
    ...
    return $maybe_modified_value;
}
//唤起过滤器钩子
add_filter( 'hook', 'example_callback', 10, 2 );
//优先级指定为10, 接收的参数个数指定为1.

6 apply_filters

6.1 格式

apply_filters( string $tag, mixed $value )

6.2 作用

“Calls the callback functions that have been added to a filter hook.”

即:“调用挂载到特定过滤器钩子上的回调函数。”

6.3 参数解析

  • $tag
    (string 类型) (必须参数) 过滤器钩子的名字。
  • $value
    (mixed 类型) (必须参数) 传递给过滤器钩子的参数。
  • $args
    (mixed 类型) (必须参数) 传递给回调函数的附加参数。

Note: apply_filters() 的返回值是是挂载到该钩子上的所有函数都执行完毕后得到的值。

6.4 使用样例

/*
要挂载到过滤器钩子上的回调函数
该回调函数需要接收3个参数
*/
function example_callback( $string, $arg1, $arg2 ) {
    // 返回 (或是是被) 修改后的 $string
    return $string;
}

/*
添加回调函数 example_callback 到过滤器钩子 example_filter
优先级: 10
需要过滤器钩子提供的参数个数: 3
*/
add_filter( 'example_filter', 'example_callback', 10, 3 );

/*
 * 唤起上面挂载到 example_filter 过滤器钩子上的 example_callback 函数
 * example_filter 是一个过滤器钩子
 * filter me 是要被过滤的值
 * $arg1 and $arg2 是要传递给回调请求的额外的值
*/
$value = apply_filters( 'example_filter', 'filter me', $arg1, $arg2 );

7 应用实例

7.1 Demo 01

Demo 01 只定义了一个过滤器,没有实现其中的代码,因此,原来的值经过过滤之后,仍以原样输出。

代码及注释:

//赋值
$zkf_value_0 = "Hello, this is ZhaoKaifeng.com";

//定义一个名为 zkf_fliter 的过滤器
//这个过滤器没挂载函数,故其实什么都没做
//将 $zkf_value_0 通过过滤器过滤后复制给 $zkf_value_1
$zkf_value_1 = apply_filters("zkf_fliter", $zkf_value_0);

//输出 $zkf_value_1
echo $zkf_value_1;

//终止接下来的执行
exit();

运行效果:

图 1.

7.2 Demo 02

Demo 02 中为过滤器添加了一个回调函数,因此,原来的值经过过滤器之后会发生变化。

代码及注释:

//回调函数
function zkf_filter_fun($zkf_value){
    return "Hi, ".$zkf_value;
}

//赋值
$zkf_value_0 = "this is ZhaoKaifeng.com";

//在过滤器钩子 zkf_fliter 上挂载一个 zkf_filter_fun 函数
//所有传递给 zkf_fliter 的变量
//都会使用 zkf_filter_fun 函数进行过滤
add_filter("zkf_fliter", "zkf_filter_fun");

//把变量 $zkf_value_0 传递给 zkf_fliter 过滤器进行过滤
//具体的过滤操作由 zkf_filter_fun 函数完成
$zkf_value_1 = apply_filters("zkf_fliter", $zkf_value_0, 10, 1);

//输出 $zkf_value_1
echo $zkf_value_1;

//终止接下来的执行
exit();

运行效果:

图 2.

References:
[1]. add_filter() | Function | WordPress Developer Resources
https://developer.wordpress.org/reference/functions/add_filter/
[2]. apply_filters() | Function | WordPress Developer Resources
https://developer.wordpress.org/reference/functions/apply_filters/

EOF