您现在的位置是:首页 > cms教程 > WordPress教程WordPress教程
wordpress的hook机制介绍
孙奎汝2025-02-08WordPress教程已有人查阅
导读稍有接触过WordPress布景或外挂客制修改的朋友,对WordPress的Hook机制应该不陌生,但通常刚接触WordPress Hook的新手,对其运作原理可能会有点混乱或模糊。本文针对WordPress Ho
稍有接触过WordPress布景或外挂客制修改的朋友,对WordPress的Hook机制应该不陌生,但通常刚接触WordPress Hook的新手,对其运作原理可能会有点混乱或模糊。本文针对WordPress Hook运作大致做个简单的说明,而预设读者是理解基本的PHP function语法及运作,但对WordPress Hook机制不是很明白。Hook机制里登场的角色
先从「登场角色」的个别说明开始:WordPress核心
指的是WordPress内建的程式码架构,提供WordPress主要的基本功能。Hook
也许你早已听说,Hook本身虽是钩子的意思,但直译又有点奇怪,所以一般通常都不直译它,而是直接称它Hook。WordPress的Hook也可以想像成「钩子」,这些「钩子」会埋在WordPress网站中特定几处的程式码中,埋进去时使用的语法,其「标示位置」的意义比较大,没有实质运作的内容。当程式执行到有埋Hook的地方时,它会找出所有对应到自己的Hook Function (也就是所有「钩到」该Hook的hook function),并一一执行。
因此若没有针对此Hook去「加入」要钩上去的Hook Function,执行到此什么也不会做。因此,它等于是WordPress核心预留一个执行的机会给未来想要加入客制功能的开发者。Hook Function
Hook Function里会有实质运作的内容,即是实作了一些客制功能,可能是存取DB、增加HTML code、执行其他函式…等。我们在Hook Function里写好所需的功能后,就可以利用「加入至对应Hook」的语法,把Hook Function自已钩到该Hook上,使得该Hook被执行到时,也会连带执行自己。Hook机制是如何运作的?
举个例子,我们拿wp_head及wp_footer这两个内建的hook来说明,wp_head这个hook就是用来埋在负责输出标签的程式码中,而wp_footer就是用来埋在输出页尾的程式码中(定义于wp-includes/general-template.php,用wp_head()及wp_footer()包装起来)。这两个hook,主要都是在布景档案中使用的,常见会出现在header.php及footer.php中。
请看下面的情境示例图,我们把wp_head及wp_footer看成是「钩子」,而别的hook functions就能来钩住它:
我们马上来写一个简单的例子。我们要写一个hook function,就叫它print_sth(),然后把它钩上wp_head这个hook。因为wp_head()的内容实际上就只有do_action('wp_head'); 这一行内容,而wp_footer()的内容也只有do_action('wp_footer');,所以我们直接把do_action的语法换到图上去,比较容易做说明,因此示意图变成:
如此,只要执行到输出header.php时,就会执行到wp_head(),就如同执行到do_action('wp_head'),此时WP核心会去找所有「钩上」wp_head这个hook的hook function,于是就找到我们写的print_sth(),然后就执行它,所以结果它做的事就会出现在网站上,也完成了「客制」的动作:
简单的说,Hook机制就是:WP核心或其他plugin、theme提供想客制功能的人一个置入客制程式码(Hook Function)到特定的执行时间点(Hook)的机会。WordPress的Action Hook与Filter Hook
WordPress中的Hook有两种,分别是「Action Hook」及「Filter Hook」,我们刚才举例的wp_head及wp_footer都是属于Action Hook。不过,一开始你可以先把这两种Hook看成是一样的东西,只是Filter多了一点点不同的特色,接着说明。Action Hook
WP核心(或布景、外挂)在做它们该做的事时,如果执行到有埋action hook的程式码(即是do_action语法) 时,会去找寻对应到的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在埋进某处程式码时所用的语法,假设我们在某处(可能是在输出页首的程式码处,或输出文章标题、文章内容、侧边栏…等地方,要「出现客制效果」的地方)埋下这两种
但如果有一个Filter Hook,它没有任何hook function有去钩它,它该怎么取得回传值?答案是,直接拿第一个它给的参数,以上面的例子来说,它会直接拿$a丢进$c。另外,其实我们也可以把filter写的跟action一样,只要不回传值就行,但action hook就没办法「模仿」filter hook,因为无法取得回传值。Hook Function的优先序(Priority)
如果有很多地方(plugin或者布景functions.php)都add同一个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的资讯,像是如下的
>>>>> wp_head1 wp_enqueue_scripts2 feed_links3 feed_links_extra8 wp_print_styles9 wp_print_head_scripts10 rsd_linkwlwmanifest_linkindex_rel_linkparent_post_rel_linkstart_post_rel_linkadjacent_posts_rel_link_wp_headlocale_stylesheetwp_generatorrel_canonicalwp_shortlink_wp_headprint_sthwp_admin_bar_header_admin_bar_bump_cb
所以,冲突很难提早避免,但发生冲突时,可以预先思考有没有可能是因为priority的设定,导致结果跟预期不符合。
先从「登场角色」的个别说明开始:WordPress核心
指的是WordPress内建的程式码架构,提供WordPress主要的基本功能。Hook
也许你早已听说,Hook本身虽是钩子的意思,但直译又有点奇怪,所以一般通常都不直译它,而是直接称它Hook。WordPress的Hook也可以想像成「钩子」,这些「钩子」会埋在WordPress网站中特定几处的程式码中,埋进去时使用的语法,其「标示位置」的意义比较大,没有实质运作的内容。当程式执行到有埋Hook的地方时,它会找出所有对应到自己的Hook Function (也就是所有「钩到」该Hook的hook function),并一一执行。
因此若没有针对此Hook去「加入」要钩上去的Hook Function,执行到此什么也不会做。因此,它等于是WordPress核心预留一个执行的机会给未来想要加入客制功能的开发者。Hook Function
Hook Function里会有实质运作的内容,即是实作了一些客制功能,可能是存取DB、增加HTML code、执行其他函式…等。我们在Hook Function里写好所需的功能后,就可以利用「加入至对应Hook」的语法,把Hook Function自已钩到该Hook上,使得该Hook被执行到时,也会连带执行自己。Hook机制是如何运作的?
举个例子,我们拿wp_head及wp_footer这两个内建的hook来说明,wp_head这个hook就是用来埋在负责输出标签的程式码中,而wp_footer就是用来埋在输出页尾的程式码中(定义于wp-includes/general-template.php,用wp_head()及wp_footer()包装起来)。这两个hook,主要都是在布景档案中使用的,常见会出现在header.php及footer.php中。
请看下面的情境示例图,我们把wp_head及wp_footer看成是「钩子」,而别的hook functions就能来钩住它:
我们马上来写一个简单的例子。我们要写一个hook function,就叫它print_sth(),然后把它钩上wp_head这个hook。因为wp_head()的内容实际上就只有do_action('wp_head'); 这一行内容,而wp_footer()的内容也只有do_action('wp_footer');,所以我们直接把do_action的语法换到图上去,比较容易做说明,因此示意图变成:
如此,只要执行到输出header.php时,就会执行到wp_head(),就如同执行到do_action('wp_head'),此时WP核心会去找所有「钩上」wp_head这个hook的hook function,于是就找到我们写的print_sth(),然后就执行它,所以结果它做的事就会出现在网站上,也完成了「客制」的动作:
简单的说,Hook机制就是:WP核心或其他plugin、theme提供想客制功能的人一个置入客制程式码(Hook Function)到特定的执行时间点(Hook)的机会。WordPress的Action Hook与Filter Hook
WordPress中的Hook有两种,分别是「Action Hook」及「Filter Hook」,我们刚才举例的wp_head及wp_footer都是属于Action Hook。不过,一开始你可以先把这两种Hook看成是一样的东西,只是Filter多了一点点不同的特色,接着说明。Action Hook
WP核心(或布景、外挂)在做它们该做的事时,如果执行到有埋action hook的程式码(即是do_action语法) 时,会去找寻对应到的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( $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)
如果有很多地方(plugin或者布景functions.php)都add同一个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_head1 wp_enqueue_scripts2 feed_links3 feed_links_extra8 wp_print_styles9 wp_print_head_scripts10 rsd_linkwlwmanifest_linkindex_rel_linkparent_post_rel_linkstart_post_rel_linkadjacent_posts_rel_link_wp_headlocale_stylesheetwp_generatorrel_canonicalwp_shortlink_wp_headprint_sthwp_admin_bar_header_admin_bar_bump_cb
所以,冲突很难提早避免,但发生冲突时,可以预先思考有没有可能是因为priority的设定,导致结果跟预期不符合。
本文标签:
很赞哦! ()
相关教程
- ansible部署lnmp和wordpress的步骤方法
- CentOS8+Nginx安装部署WordPress的步骤方法
- WordPress的Google字体导致加载速度慢的解决方法
- 基于Centos7详细安装wordpress的方法
- Ubuntu系统lnmp框架搭建WordPress的方法
- Wordpress的Shell的使用方法介绍
- docker搭建WordPress的步骤方法教程
- mariadb和nginx搭建wordpress的方法
- lnmp安装nginx搭建wordpress的方法
- openEuler中基于LAMP部署WordPress的方法
- CentOS8搭建LNMP+WordPress的步骤方法
- centos安装部署wordpress的方法步骤
图文教程
实现WordPress支持上传SVG格式图片并显示在媒体库中的方法
因SVG格式图片特性,可能会入恶意代码,网站容易被攻击,所以出于安全考虑WordPress默认不支持SVG格式图片上传
wordpress添加备案信息的解决方法
备案时,需要显示备案号,而wordpress默认模板本身不带这个信息,为了更快速应付备案,解决方案如下:
wordpress制作新闻列表的仿站步骤
wordpress新闻列表如何制作,WordPress新闻文章列表页仿站步骤1、制作archive.php页面2、调用header、sidebar、footer文件
WordPress文件权限安全配置
每个主机和主机的情况可能有所差异,如下只是概括性地描述,并不一定适用于所有情况。它只适用于进行“常规设置”的情况(注:比如通过“suexec”方式来进行共享主机的,详情见下方)
相关源码
-
帝国cms7.5淘宝客电商品牌特价带手机站带会员模板下载为电商品牌特价展示设计的帝国CMS模板,集成PC端与移动端双平台适配。采用瀑布流商品布局,支持品牌分类聚合展示,突出特价促销视觉冲击力。查看源码 -
(响应式H5)帝国cms7.5文章新闻博客模板带会员中心本模板基于帝国CMS内核开发,为新闻资讯、个人博客及作品展示类网站设计。采用响应式布局技术,确保在手机、平板和电脑等不同设备上都能获得良好的浏览体验。查看源码 -
(PC+WAP)绿色日志美文文学说说博客网站pbootcms模板除日志博客类网站外,通过替换图文内容可快速适配:心情日记分享平台、文学创作社区、朋友圈内容聚合站、美文鉴赏网站、读书笔记平台等应用场景。查看源码 -
(PC+WAP)绿色资源回收新能源环保设备pbootcms源码下载基于PbootCMS系统深度开发的环保行业模板,特别适配资源回收设备、新能源技术、环境治理装备等企业的线上展示需求。集成产品库、解决方案、环保案例等专业模块,助力企业高效传递绿色价值。查看源码 -
(PC+WAP)货物运输快递物流汽车贸易pbootcms模板下载为货运代理、汽车贸易及快递企业设计的全终端适配网站系统,整合运单追踪与车辆展示核心功能模块原生开发的DIV+CSS架构,支持WebP图像压缩技术。查看源码 -
(自适应)摄像头安防电子设备pbootcms源码下载本模板基于PbootCMS系统开发,为安防电子设备企业设计,特别适合监控摄像头、安防系统等产品的展示。采用响应式技术,确保各类设备参数和功能在不同终端上都能清晰呈现。查看源码
| 分享笔记 (共有 篇笔记) |

