钩子(hook)这个概念,我之前在这个站写过几篇:add_filter 是 WordPress 独有的吗、apply_filters 怎么找到你的函数。这篇不重复那些,只讲一个最基础的问题:add_action 和 add_filter 到底差在哪。
两个都是“往钩子上登记一个函数”,区别是要不要返回值:
add_action:登记的函数不需要返回值(返回值会被忽略);add_filter:登记的函数必须返回值(返回值会替换原内容)。用类比说:
add_action( 'publish_post', function ( $post_id ) {
// 文章发布了,做点事(发邮件、清缓存……)
// 不需要 return
} );
这里你 return 什么,WordPress 都不管。它的关注点是“这件事发生了”。
add_filter( 'the_title', function ( $title ) {
return $title . ' | 草根站长笔记'; // 必须返回
} );
这里必须 return。不返回的话,标题就变成空的了——因为 WordPress 用你的返回值替换原标题,你返回 null,标题就没了。
在 filter 里忘了 return:
add_filter( 'the_content', function ( $content ) {
$content .= '<p>本文完</p>';
// 忘了 return $content;
} );
结果:全站文章正文全部消失。
因为 filter 拿你的返回值去替换原内容,你返回 null,内容就空了。这个 bug 特别吓人,但原因特别简单。
看钩子名字的“动词”:
publish_post、wp_head、init)→ 用 add_action;the_title、the_content、wp_title)→ 用 add_filter。更准确的方法:查 WordPress 文档,看它是 do_action() 触发的还是 apply_filters() 触发的。do_action 配 add_action,apply_filters 配 add_filter。
写错了会怎样?用 add_action 挂到 apply_filters 上,函数会被调用,但返回值被忽略——等于“加工了但没用上”。用 add_filter 挂到 do_action 上,返回值也没人接——等于白写。
两种都不报错,只是“没效果”。这也是钩子最难查的地方。
一句话记住:add_action 是“通知”,不用返回值;add_filter 是“加工”,必须返回值。不返回 = 内容消失。
下一篇讲优先级和 remove_action——为什么有时候删不掉。