上一篇讲清了 apply_filters() 是”按名字点名”,而不是广播。紧接着就有读者追问了一个更实际的问题:
在其它地方也会调用其它的函数吧?也是同样多的参数吗?还是说会根据调用的函数不同,WordPress 核心会内置不同的参数?
这个问题问到点子上了——因为答案直接决定你写函数签名时该写几个参数。这篇文章把它讲透。
WordPress 核心没有一套”所有钩子都必须遵守”的参数规范。它是一个变参函数——内核在那个点上手里有多少东西想递给你,就递多少。
看它自己的签名就明白了:
apply_filters( string $hook_name, mixed $value, mixed ...$args )
// ↑钩子名 ↑主角值 ↑可变参数,想递几个递几个
那个 ...$args 就是关键:它表示”后面跟的数量不固定”。内核可以只递一个,也可以递六个。
别猜,直接看源码。我把四个常用调用点的原句都抓了出来:

| 调用点 | 内核源码 | 递几个 | 类型 |
|---|---|---|---|
| 正文 | $content = apply_filters( 'the_content', $content ); |
1 个 | string |
| 头像 | return apply_filters( 'get_avatar', $avatar, $id_or_email, $args['size'], $args['default'], $args['alt'], $args ); |
6 个 | string + mixed + int + string + string + array |
| 摘要长度 | $excerpt_length = (int) apply_filters( 'excerpt_length', $excerpt_length ); |
1 个 | int |
| 网页标题 | $title = apply_filters( 'wp_title', $title, $sep, $seplocation ); |
3 个 | string × 3 |
注意第三行最后那个 (int) 强转——连类型都不固定。excerpt_length 递给你的是整数 55,不是字符串。你要是 return 'abc',会被强转成 0,摘要直接变空。这不是理论风险,是真实会发生的坑。
参数个数千变万化,但规矩只有两条,比记数字重要得多。
不管后面跟几个,第二个位置上传的那个值(也就是你函数签名里的第一个参数)永远是被过滤的东西本身:the_content 递的是正文、get_avatar 递的是头像 HTML、excerpt_length 递的是数字、wp_title 递的是标题。
你的函数把它改完,必须 return 它。不 return,WordPress 拿到的就是空值。
以 get_avatar 为例,它递了 6 个,但后 5 个只是告诉你”这个头像是谁的、多大尺寸、alt 文本是什么”——目的是让你有条件地改,而不是让你改它们本身。你只 return 第一个($avatar)就对了。
这一点可以直接对照我自己的代码。我那个换头像域名的函数签名只有一个参数:
function liu_replace_gravatar($avatar) {
// 只换域名,用不上其他信息
...
return $avatar;
}
这是对的——我的任务只是把 HTML 里的域名换掉,不需要知道头像是谁的。
但反过来,如果我想实现”只给 96 像素以下的小头像换域名,大图保留”,那就必须多接参数,接到 $size:
function liu_replace_gravatar($avatar, $id_or_email, $size) {
if ( $size <= 96 ) {
// 只处理小头像
}
return $avatar;
}
add_filter( 'get_avatar', 'liu_replace_gravatar', 10, 3 ); // 注意这里要写 3
顺便复习上一篇:最后一个参数决定了你能接几个。这里写 3,第三个参数才递得到手;还写默认的 1,$size 就是 undefined,判断永远不成立。
两个办法,都不用猜:
get_avatar 的页面标题直接写着 apply_filters( 'get_avatar', string $avatar, mixed $id_or_email, ... ),几个参数、什么类型一目了然;apply_filters( '钩子名',那一行就是答案,比任何教程都准。excerpt_length 的官方示例专门把优先级设成了 999:
add_filter( 'excerpt_length', 'mytheme_custom_excerpt_length', 999 );
原因是 WordPress 自己也挂了一个默认过滤器在这个钩子上,而且它跑得比你晚——你不抢到它后面,你的设置就会被覆盖掉。这是”多个函数改同一个值”的真实案例,也再次说明:抄教程时,那个数字不是摆设。
apply_filters 是变参函数:参数个数和类型跟着调用点走;你只需要关心第一个参数是什么、以及要不要 return 它,后面递的都是参考资料。
所以新手遇到”照着教程抄的函数签名,怎么到我这儿就报 undefined”,十有八九是抄错了参数个数——每个钩子的函数签名都是专属的,没有通用模板。抄代码时连 add_filter 最后那个数字一起抄,别只抄函数体。
(这是 WordPress 踩坑系列的第七篇,前一篇是 钩子不是广播,是点名。)