抄教程的函数签名为什么报错?apply_filters 递给你几个参数,是调用点自己定的

作者: admin 分类: wordpress主题制作教程 发布时间: 2026-10-14 13:25

上一篇讲清了 apply_filters() 是”按名字点名”,而不是广播。紧接着就有读者追问了一个更实际的问题:

在其它地方也会调用其它的函数吧?也是同样多的参数吗?还是说会根据调用的函数不同,WordPress 核心会内置不同的参数?

这个问题问到点子上了——因为答案直接决定你写函数签名时该写几个参数。这篇文章把它讲透。

一、先给答案:没有统一模板,递几个完全由调用点自己决定

WordPress 核心没有一套”所有钩子都必须遵守”的参数规范。它是一个变参函数——内核在那个点上手里有多少东西想递给你,就递多少。

看它自己的签名就明白了:

apply_filters( string $hook_name, mixed $value, mixed ...$args )
//              ↑钩子名           ↑主角值       ↑可变参数,想递几个递几个

那个 ...$args 就是关键:它表示”后面跟的数量不固定”。内核可以只递一个,也可以递六个。

二、四个真实调用点的对比

别猜,直接看源码。我把四个常用调用点的原句都抓了出来:

四个 WordPress 调用点递出参数个数对比图
同一个 apply_filters(),递几个参数完全由调用点自己决定
调用点 内核源码 递几个 类型
正文 $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,摘要直接变空。这不是理论风险,是真实会发生的坑。

三、真正要记住的是两条铁律

参数个数千变万化,但规矩只有两条,比记数字重要得多。

铁律一:第一个参数永远是”主角值”,你必须 return 它

不管后面跟几个,第二个位置上传的那个值(也就是你函数签名里的第一个参数)永远是被过滤的东西本身: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,判断永远不成立。

四、怎么查某个钩子到底递几个

两个办法,都不用猜:

  1. 查官方文档:developer.wordpress.org 搜”钩子名 + hook”,页面大标题就是完整签名。比如 get_avatar 的页面标题直接写着 apply_filters( 'get_avatar', string $avatar, mixed $id_or_email, ... ),几个参数、什么类型一目了然;
  2. grep 源码:在 WordPress 核心目录里搜 apply_filters( '钩子名',那一行就是答案,比任何教程都准。

五、一个容易被忽略的细节:优先级也可能要抢

excerpt_length 的官方示例专门把优先级设成了 999:

add_filter( 'excerpt_length', 'mytheme_custom_excerpt_length', 999 );

原因是 WordPress 自己也挂了一个默认过滤器在这个钩子上,而且它跑得比你晚——你不抢到它后面,你的设置就会被覆盖掉。这是”多个函数改同一个值”的真实案例,也再次说明:抄教程时,那个数字不是摆设。

六、收个尾

apply_filters 是变参函数:参数个数和类型跟着调用点走;你只需要关心第一个参数是什么、以及要不要 return 它,后面递的都是参考资料。

所以新手遇到”照着教程抄的函数签名,怎么到我这儿就报 undefined”,十有八九是抄错了参数个数——每个钩子的函数签名都是专属的,没有通用模板。抄代码时连 add_filter 最后那个数字一起抄,别只抄函数体。

(这是 WordPress 踩坑系列的第七篇,前一篇是 钩子不是广播,是点名。)

相关文章

搜索文章:
联系方式:
Powered by 草根站长笔记 © 2015-2020 草根站长笔记 Inc.版权所有,禁止转载