WordPress动作钩子函数add_action()、do_action()源码解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介:

WordPress常用两种钩子,过滤钩子和动作钩子。过滤钩子相关函数及源码分析在上篇文章中完成,本篇主要分析动作钩子源码。

 

然而,在了解了动作钩子的源码后你会发现,动作钩子核心代码竟然跟过滤钩子差不多!是的,至此,我不得不告诉你,动作钩子只是WP开发者为了区分概念而把过滤钩子另外命名的一种东西!当然,它们还是有一些细微的差别,下面我们将从源码来深入解读。

 

动作钩子概念:动作钩子是WP代码执行到某处或某个事件发生时触发的一系列函数,插件可以利用动作钩子API在WP代码执行的特定点之前插入一系列函数以控制执行。它跟过滤钩子极像,唯一不同的是过滤钩子返回一个处理后的值,而动作钩子仅完成函数执行并不返回值,如果钩子不存在则返回NULL并新增该钩子。

 

动作钩子原理:由于动作钩子和过滤钩子几乎一样,所以它们的实现原理也是一样的。它主要利用一个全局变量$wp_filter,增加动作函数时使用add_action()函数给全局变量$wp_filter增加了一个数组元素,这个元素键名中含有钩子名,值中含有对应函数及执行优先级等信息,在调用do_action()函数使用动作钩子时,它通过循环查找出所有跟钩子关联的函数并将其依次调用,最后返回处理后的数据。

 

动作钩子使用步骤

由于PHP代码会经过Zend等引擎翻译,代码中步骤的先后顺序并不重要,所以以下步骤仅为便于理解钩子原理的伪步骤,不具有实际参考意义!

1、创建钩子(可省略):使用do_action()函数可以创建一个没有挂载函数的钩子,挂载函数可以通过add_action()添加,最后再使用do_action()调用执行;

2、创建动作函数:它可以有传入参数也可以无传入参数,其他与创建普通函数没有任何区别,函数的作用为完成某项动作;

3、挂载函数:即使用add_action()将函数挂载到指定钩子上;

4、执行动作钩子:使用do_action()可以依次执行挂载在指定钩子上的所有函数以完成指定任务;

 

动作钩子函数详解:

在看动作钩子函数作用、参数说明等时,你会发现几乎是跟过滤钩子重复的。至于为什么会这样,那就要看源码了,我保证,看完源码后你会感慨自己被WP开发者涮了!

1、add_action($tag,$function_to_add,$priority = 10,$accepted_args = 1)

add_action()作用:该函数用于给指定的动作钩子$tag添加指定的挂载函数$function_to_add,同时它可以确定挂载函数执行优先级及其可接收参数个数;

add_action()参数说明

$tag为钩子名;

$function_to_add为挂载函数名;

可选参数$priority为该挂载函数执行的优先级,默认为10,该数字越小则越早执行,数字相同则按其添加到钩子上的顺序执行,越早添加越早执行;

可选参数$accepted_args确定挂载函数接收的参数个数,默认为1;

add_action()源码分析:

function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
    return add_filter($tag, $function_to_add, $priority, $accepted_args);
}

 

怎么样,看到了吧!被坑了有木有!add_action()函数的代码竟然是调用一次add_filter()!这尼玛完全是一个人的大名和小名的问题有木有!

 

2、do_action($tag, $arg = '')

do_action()作用:该函数调用挂载在过滤钩子$tag上的所有函数以完全特定的任务;

do_action()参数说明:

$tag为钩子名;

$arg为动作钩子上挂载函数的传入参数,默认为空;

do_action()源码分析:

复制代码
function do_action($tag, $arg = '') {
    global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
    if ( ! isset($wp_actions) )
        $wp_actions = array();
# 如果$wp_actions变量未设置过,则将其定义为数组;
    if ( ! isset($wp_actions[$tag]) )
        $wp_actions[$tag] = 1;
    else
        ++$wp_actions[$tag];
    # 如果$wp_actions[$tag]未设置则将其赋值为1,否则将其值加1;
    if ( isset($wp_filter['all']) ) {
        $wp_current_filter[] = $tag;
        $all_args = func_get_args();
        _wp_call_all_hook($all_args);
    }
    # 跟apply_filters()中的all钩子处理方式完全一样!_wp_call_all_hook()源码分析见上篇文章过滤钩子源码解析;
    if ( !isset($wp_filter[$tag]) ) {
        if ( isset($wp_filter['all']) )
            array_pop($wp_current_filter);
        return;
    }
    # 当前钩子不存在,则直接返回,不再执行以后代码;
    if ( !isset($wp_filter['all']) )
        $wp_current_filter[] = $tag;
    # 将当前钩子设置为$tag;
    $args = array();
    if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) )
        $args[] =& $arg[0];
    else
        $args[] = $arg;
    # do_action()若有传入参数,且为一个数组,该数组仅此一个元素,该元素有值则将$args值设置为引用$arg[0],否则直接赋值;
    for ( $a = 2; $a < func_num_args(); $a++ )
        $args[] = func_get_arg($a);
    # 通过for循环,若do_action()有不只一个传入参数,将这些值赋给数组$args;
    if ( !isset( $merged_filters[ $tag ] ) ) {
        ksort($wp_filter[$tag]);
        $merged_filters[ $tag ] = true;
    }
    # 跟apply_filter()函数排序代码完全一样!详解见上文;
    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);
}
    # 除了少了一行return $value其他跟apply_filters()完全一样!


本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/p/4773993.html,如需转载请自行联系原作者
相关文章
|
1月前
|
SQL 数据挖掘 测试技术
南大通用GBase8s数据库:LISTAGG函数的解析
南大通用GBase8s数据库:LISTAGG函数的解析
|
3天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
3天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
3天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
27天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
54 12
|
22天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
25天前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
35 5
|
4天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
5月前
【wordpress教程】wordpress博客网站添加非法关键词拦截
有的网站经常被恶意搜索,站长们不胜其烦。那我们如何屏蔽恶意搜索关键词呢?下面就随小编一起来解决这个问题吧。
90 1
|
2月前
|
XML 搜索推荐 机器人
五个 WordPress 插件可提高网站参与度
五个 WordPress 插件可提高网站参与度

热门文章

最新文章

推荐镜像

更多