WordPress钩子Action Hook与Filter Hook
WordPress钩子Action Hook与Filter Hook
WordPress的Action Hook与Filter Hook
WordPress中的 Hook 有两种,分别是Action Hook及Filter Hook,一开始你可以先把这两种 Hook 看成是一样的东西,只是 Filter 多了一点点不同的特色,接着说明。
Action Hook
WP核心 (或主题、插件)在做它们该做的事时,如果执行到有埋action hook
的代码时,会去找寻对应到的hook functions,进而执行这些hook functions(即那些透过 add_action()
来加入的hook functions),藉此完成定制功能。WP核心并不期待Action Hook functions 会有回传值,所以这里的hook function只被视为一个”独立切出来运作的功能“。
WP核心做它该做的事,你做你想做的事,做完就各自结束。
Filter Hook
跟Action Hook一样,WP核心 (或主题、插件)在做它们该做的事时,如果执行到有埋 filter hook的代码即是apply_filters
语法) 时,就会去找寻对应的hook functions,进而执行这些 hook functions(即那些透过add_filter()
来加入的hook functions),藉此完成定制功能。与 Action Hook不同之处是,所有”鈎上“ Filter Hook的hook functions通常都会接收到参数,而WP核心会期待你拿到它提供的参数,并做完你想做的事后,要回传(return
)一个值,让WP核心再利用你回传的值来接着完成它该做的事。
透过你的干涉,修改了WP核心丢给你的参数,WP核心再接着拿你改过的参数,继续完成它该做的事,此动作就像”过滤“的动作,因而得名filter。
比较Action Hook与Filter Hook的操作语法
比较一下两种 Hook 在埋进某处程式码时所用的语法,假设我们在某处 (可能是在输出页首的程式码处,或输出文章标题、文章内容、侧边栏…等地方,要”出现定制效果“的地方)埋下这两种 hook:
/*--------------- Action Hook ---------------*/
// 埋下一个名叫'do_more'的action hook
do_action('do_more');
/*--------------- Filter Hook ---------------*/
// 埋下一个名叫'get_special'的filter hook,注意它会有回传值
$c = apply_filters('get_special',$a, $b);
然后我们可以在某处 (可能是其他插件、functions.php 等处,要”实现定制功能“的地方)添加对应的hook function:
/*--------------- Action Hook Function---------------*/
// 增加要钩上'do_more'这个hook的hook function,
// 并为此hook function取名叫more_func。
// 第一个参数是hook名称、第二个是hook function名称
add_action('do_more', 'more_func');
// 添加more_func的內容,不需回传值
function more_func()
{
echo 'do more thing...';
}
/*--------------- Filter Hook Function ---------------*/
// 增加要钩上'get_special' hook的hook function,
//并为此hook function取名叫special_func。
// 参数1是hook名称、参数2是hook function名称
// 参数3是Priority(优先序)、参数4是hook function参数的数目
add_filter('get_special', 'special_func', 10, 2);
// 添加special_func的內容,需要給它回传值
function special_func($a, $b)
{
$c = $a.' & '.$b; //做一些事,例如把两个参数连接起來
return $c; //回传值
}
所以其实两种 Hook 的运作方式几乎一样,只差在增加Action Hook函数不需要回传值,而增加Filter Hook function时,你必须要回传一个值。所以Filter Hook函数通常都有提供参数,让想定制的人可以取得它,处理后再回传。
但如果有一个Filter Hook,它没有任何hook function有去钩它,它该怎么取得回传值?答案是,直接拿第一个它给的参数,以上面的例子来说,它会直接拿$a
丢进$c
。另外,其实我们也可以把filter写的跟action一样,只要不回传值就行,但action hook就没办法”模仿“ filter hook,因为无法取得回传值。
Hook Function的优先序(Priority)
如果有很多地方(主题或者插件的 functions.php)都 添加同一个 hook ,会怎么决定出现顺序?答案很显然是可以透过Hook Function的Priority
参数来作优先序的设定:
就像我们刚才说明的例子中,我们使用add_filter
加入special_func
时设定的优先序是 10 ,这也是Priority
参数的预设值。如果你希望它能优先被执行,就设定小于 10 的数字,反之,就设个 100、500 之类的,让它延后被执行。
但其实这里有个隐含的冲突问题。
以 wp_head 这个 hook 为例,如果我写了一个插件,希望透过 wp_head 来输出”增加 a.css 档案“的 HTML 语法,而 a.css 会重新设定 body 元素的样式,所以我希望它可以最后才被汇入,不要被其他 css 档干扰,于是我将 Priority 设为 900,但我怎么知道 Priority 900 够不够大?若某个WP网站,它除了安装我的插件,也安装了其他插件,而其他插件刚好也重新设定body元素的样式,然后把 Priority 设为 950,此时我写的插件在处理 body 样式时就出事了,于是就跟其他插件冲突了。
所以此时我们需要了解的是:我的WP网站可能装了很多插件,我怎么知道同一个Hook被加了多少 Hook Function,而每个Hook Function的 Priority 被设定为多少?
答案是,我们可以透过$wp_filters
这个global
变数来取得所有hook的信息,像是如下的function:
// 列出所有的hook function及其priority
function list_hooked_functions($tag=false)
{
global $wp_filter;
if ($tag)
{
$hook[$tag]=$wp_filter[$tag];
if (!is_array($hook[$tag]))
{
trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
return;
}
}
else
{
$hook=$wp_filter;
ksort($hook);
}
echo '<pre>';
foreach($hook as $tag => $priority)
{
echo "<br />>>>>>\t<strong>$tag</strong><br />";
ksort($priority);
foreach($priority as $priority => $function)
{
echo $priority;
foreach($function as $name => $properties) echo "\t$name<br />";
}
}
echo '</pre>';
return;
}
当我们调用list_hooked_functions('wp_head');
时,就会列出 wp_head 这个 Hook 所钩住的所有hook function,可以看到priority 10 之后有好几个都没有数字,因为它们都没有特别指定 priority,所以都是 10 ,包括我们刚才写的print_sth
也在其中:
>>>>> wp_head
1 wp_enqueue_scripts
2 feed_links
3 feed_links_extra
8 wp_print_styles
9 wp_print_head_scripts
10 rsd_link
wlwmanifest_link
index_rel_link
parent_post_rel_link
start_post_rel_link
adjacent_posts_rel_link_wp_head
locale_stylesheet
wp_generator
rel_canonical
wp_shortlink_wp_head
print_sth
wp_admin_bar_header
_admin_bar_bump_cb
所以,冲突很难提早避免,但发生冲突时,可以预先思考有没有可能是因为 priority 的设定,导致结果跟预期不符合。
- 分类:
- WordPress
相关文章
小改wordpress的get_permalink,支持固定链接设置值和插件获取值不同
因为本站的前端展示放弃使用WordPress博客系统的,而是改用自己的vue服务端渲染了,在保留原来的链接地址(比如 https://www.daozhao.com/8531.html )不变的情h 阅读更多…
参考教程实现WordPress更新博文通知钩子插件
搞一个更新博客文章的钩子插件,目前的功能是更新自己的PWA缓存版本 <?php /* Plugin Name: Daozhao Blog Description: wordp 阅读更多…
sae-eclipse插件加新浪sae进行java项目开发
1.首先当然是下载eclipse和sae-eclipse插件喽,sae-eclipse的 下载地址 . 2.在eclipse新建一个Dynamic Web Project ,然后再在WebCon 阅读更多…
wordpress使用多说插件后带来的问题
今天本想做个新建个页面,做个联通账号在线解密页面,以解决部分网友在路由器中输入“正确的”联通宽带的账号但无法拨号成功的问题,但是发现我使用自定义模板的方式创建的页面并没有如我的意愿来显示,而只是光秃秃 阅读更多…
CKEditor富文本编辑器职责分离
背景 CKEditor富文本 编辑器 (生产版本1.1.1及以前)里面包含富文本基础插件及当前最新的邮件特定的业务插件(签名、快捷回复、邀评、默认样式、选择颜色、插入图片、粘贴模式) O端 阅读更多…
参考教程实现WordPress更新博文通知钩子插件
搞一个更新博客文章的钩子插件,目前的功能是更新自己的PWA缓存版本 <?php /* Plugin Name: Daozhao Blog Description: wordp 阅读更多…