您现在的位置是:首页 > cms教程 > WordPress教程WordPress教程
WordPress的HOOK机制原理代码分析
慕青2025-03-19WordPress教程已有人查阅
导读WordPress强大的插件机制让我们可以自由扩展功能。网上对插件的使用以及开发方法都有大量资料可以查询。今天我们就分析一下四个主要函数的代码,包括:
WordPress强大的插件机制让我们可以自由扩展功能。网上对插件的使用以及开发方法都有大量资料可以查询。
今天我们就分析一下四个主要函数的代码,包括:
add_action、do_action、add_filter、apply_action。
一、add_action和add_filter
为什么把这两个函数放在一起讲呢?其实我们看看add_action函数的定义(图一)就可以知道,其实跟add_filter是同一个函数,执行的是相同的操作。只是把action和filter区分开,让开发者能更好地开发插件而设置的。
这里我们以两个挂钩作为例子来讲解。很明显它的结构是这样子的:
我们继续分析代码。
函数定义:
前两个变量在前面已经做了说明了,$wp_actions是记录action被调用的次数,$wp_current_filter是记录当前使用的action的信息,它是一个堆栈结构,当出现递归调用的时候就非常有用了。
系统会先记录这个action的调用次数。然后再把当前调用的挂钩记录起来。查找有没有通用的挂钩函数,有的话就执行。接着检查有没有指定的挂钩函数,没有的话就把$wp_current_filter里相应的元素弹出,并把跳出函数返回。
如果挂钩下有相应的函数的话,那么先把要传递给函数的参数放到数组里面,再进行优先级排序,之后再一一执行。之后还是要把$wp_current_filter里相应的元素弹出。
三、apply_filter
函数定义:
1、它并不记录该挂钩运行的次数。
2、由于它传入的都是一个字符串类型的参数,所以它的参数存储比较简单。
3、处理完所有函数后,会把最终处理结果返回。
reference from : http://caord.ynot.cn/?p=467
今天我们就分析一下四个主要函数的代码,包括:
add_action、do_action、add_filter、apply_action。
一、add_action和add_filter
为什么把这两个函数放在一起讲呢?其实我们看看add_action函数的定义(图一)就可以知道,其实跟add_filter是同一个函数,执行的是相同的操作。只是把action和filter区分开,让开发者能更好地开发插件而设置的。
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1)
{
return add_filter($tag, $function_to_add, $priority, $accepted_args);
}
现在我们再看看add_filter的函数定义:
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
global $wp_filter, $merged_filters;
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add,
'accepted_args' => $accepted_args);
unset( $merged_filters[ $tag ] );
return true;
}
函数的第一行就是定义$wp_filter和$merged_filters。$wp_filter是一个多维数组,保存了目前所有的已注册在挂钩上的函数的信息。把它扩展开可以看到这样子的结构:这里我们以两个挂钩作为例子来讲解。很明显它的结构是这样子的:
$wp_filter=array(
'挂钩名'=>array(
'优先级'=>array(
'函数1'=>array(
'function'=>"函数名",
'accepted_args'=>"函数接受的参数数量"
),
'对象'=>array(
'function'=>array(
'0'=>'对象的引用',
'1'=>'对象上的方法'
),
'accepted_args'=>"方法接受的参数数量"
)
)
)
);
那么$merged_filter是什么呢?其实在这个函数里并没有体现出它的作用。但是如果我们结合do_action函数里的代码。
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
我们可以知道,当相应的挂钩下的函数被调用的时候,它会对这些函数进行优先级排序,当排完序的时候,$merged_filters下对应的函数就 会被设置为true。而当我们在相应挂钩下添加一个函数的时候,它在$merged_filters数组下的值会被删除。说白了,它就是一个标识,用来说 明这个标识下的函数是否已经经过优先级排序。我们继续分析代码。
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
这句代码里的函数我们就不展开去读了,我们只需要知道它返回的是下面这部分的内容就行了。
'函数1'=>array(
'function'=>"函数名",
'accepted_args'=>"函数接受的参数数量"
),
'对象'=>array(
'function'=>array(
'0'=>'对象的引用',
'1'=>'对象上的方法'
),
'accepted_args'=>"方法接受的参数数量"
)
接下来的这句代码也很简单,就是把函数配置到挂钩上面去而已。
$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
因为这里插入了一条函数,可能改变了它下面的函数的执行优先级,所以这里的标识要删除。
unset( $merged_filters[ $tag ] );
二、do_action函数定义:
function do_action($tag, $arg = '') {
global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
if ( ! isset($wp_actions) )
$wp_actions = array();
if ( ! isset($wp_actions[$tag]) )
$wp_actions[$tag] = 1;
else
++$wp_actions[$tag];
$wp_current_filter[] = $tag;
if ( isset($wp_filter['all']) ) {
$all_args = func_get_args();
_wp_call_all_hook($all_args);
}
if ( !isset($wp_filter[$tag]) ) {
array_pop($wp_current_filter);
return;
}
$args = array();
if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
$args[] =& $arg[0];//参数是个数组,并且只有一个元素,并且这个元素不为空,而且是一个对象。
else
$args[] = $arg;
for ( $a = 2; $a < func_num_args(); $a++ )
$args[] = func_get_arg($a);
// Sort
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
reset( $wp_filter[ $tag ] );
do {
foreach ( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) )
call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
} while ( next($wp_filter[$tag]) !== false );
array_pop($wp_current_filter);
}
第一条语句定义了几个全局函数:$wp_filter,$merged_filters,$wp_actions,$wp_current_filter。前两个变量在前面已经做了说明了,$wp_actions是记录action被调用的次数,$wp_current_filter是记录当前使用的action的信息,它是一个堆栈结构,当出现递归调用的时候就非常有用了。
系统会先记录这个action的调用次数。然后再把当前调用的挂钩记录起来。查找有没有通用的挂钩函数,有的话就执行。接着检查有没有指定的挂钩函数,没有的话就把$wp_current_filter里相应的元素弹出,并把跳出函数返回。
如果挂钩下有相应的函数的话,那么先把要传递给函数的参数放到数组里面,再进行优先级排序,之后再一一执行。之后还是要把$wp_current_filter里相应的元素弹出。
三、apply_filter
函数定义:
function apply_filters($tag, $value) {
global $wp_filter, $merged_filters, $wp_current_filter;
$args = array();
$wp_current_filter[] = $tag;
// Do 'all' actions first
if ( isset($wp_filter['all']) ) {
$args = func_get_args();
_wp_call_all_hook($args);
}
//如果钩子上没有这个函数,那么把函数挂到这个钩子上去。
if ( !isset($wp_filter[$tag]) ) {
array_pop($wp_current_filter);
return $value;
}
// Sort 对挂钩上面的函数根据优先级进行排序,将$merged_filters[$tag]设置为真
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
//把数组指针重新定回首部
reset( $wp_filter[ $tag ] );
//获得参数
if ( empty($args) )
$args = func_get_args();
// 对挂钩上的每一个函数进行处理
do {
foreach( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) ){
$args[1] = $value;
$value = call_user_func_array($the_['function'], array_slice($args, 1,
(int) $the_['accepted_args']));
}
} while ( next($wp_filter[$tag]) !== false );
array_pop( $wp_current_filter );
return $value;
}
仔细一看,你会发现它的代码跟do_action差不多。是的!它跟do_action有几点区别:1、它并不记录该挂钩运行的次数。
2、由于它传入的都是一个字符串类型的参数,所以它的参数存储比较简单。
3、处理完所有函数后,会把最终处理结果返回。
reference from : http://caord.ynot.cn/?p=467
本文标签:
很赞哦! ()
相关教程
图文教程
docker搭建wordpress博客的实现方法
环境:centos7、docker、vmwareworkstation虚拟机1 拉取mysql:5.7 镜像,使用mysql镜像运行一容器2 运行容器 查看状态3 拉取wordpress镜像4 运行wordpress 容器,查看状态
WordPress批量修改文章信息的方法
你是否遇到过如下几种状况:博客更换域名,博客文章的内容也要跟着换使用的图片地址更换了写了很多文章,回过头来想切换作者想删除某个可恶留言者的所有留言想更改某个留言者所有留言的网站
WordPress主题模板按评论数量显示前100名评论者的方法
如想看看自己博客上哪位博友的留言评论最多及最后的评论时间,下面一段代码会帮你实现这个功能。
wordpress可以做什么网站,wordpress可以做哪些网站
wordpress能建的网站:1、博客与个人网站,可以让站点变得更加精致、成熟;2、商业网站或者企业官网,它为用户提供了便捷的工具,可以快速启动网站
相关源码
-
(自适应响应式)HTML5简繁双语电子元器件设备制造Pbootcms模板下载本模板为电子科技设备制造、电子元件生产等高科技企业设计,采用PbootCMS内核开发,具备简繁双语切换功能。模板设计充分考虑了电子科技行业的技术展示需求,能够专业呈现各类电子元器件、电路板、智能设备的参数规格和应用方案。查看源码 -
(PC+WAP)门窗门业家居定制铝合金产品pbootcms模板下载基于PbootCMS内核开发的门窗门业企业专用模板,采用响应式设计结构,数据一次录入即可同步适配电脑与手机端浏览。通过简洁大气的视觉呈现,帮助门窗企业快速建立专业线上展示平台,有效传递产品价值与服务优势。查看源码 -
(PC+WAP)红色厨具厨房用品设备pbootcms模板源码下载为厨具设备企业设计的响应式网站模板,采用PbootCMS内核开发,适用于商用厨房设备、家用厨具、厨房用品等企业展示。模板包含产品展示、新闻动态、案例中心等标准模块,助您快速搭建专业级行业网站。查看源码 -
(自适应)蓝色基建施工工程建筑集团网站pbootcms模板下载为工程建筑、基建施工类企业打造的PbootCMS模板,采用现代化设计理念,突出企业实力与项目展示,帮助建筑类企业快速建立专业在线门户。查看源码 -
自适应黑色简繁双语轴承齿轮机械设备制造网站模板该模板为轴承齿轮机械制造企业提供一体化网站建设方案,着重解决行业特有的多语言展示、移动端适配和高效率内容管理需求,帮助企业精准展示产品特性与工艺流程查看源码 -
(PC+WAP)五金机械设备营销型模板下载带在线留言为机械设备制造商设计的营销型模板,集成产品参数对比系统、产品展示模块和询价管理功能。采用PbootCMS开发内核,PHP7+运行环境。手工编写语义化HTML5结构,CSS3动画优化交互体验。查看源码
| 分享笔记 (共有 篇笔记) |

