我在问高级的东西。如何在PHP中实现?例如,它如何收集来自不同插件的所有钩子,并将它们“附加”到核心钩子等。

评论

据我所知,php中没有“钩子”或“过滤器”,有功能。 WordPress具有一些特殊功能,在执行之前,它们会使用其他功能的回调。

相关:wordpress.stackexchange.com/questions/103641/…

@OfirBaruch,我很确定OP指的是它们在WordPress中的实现,而不是在暗示它本身有一些PHP实现。

#1 楼

概述

基本上,召唤过滤器和挂钩的“插件API”由以下功能组成:




apply_filters()-执行


do_action-执行


apply_filters_ref_array()-执行


do_action_ref_array()-执行


add_filter()-添加到堆栈


add_action()-添加到堆栈


基本内部构件

总体有几个全局变量(在WordPress世界中是什么):

global $wp_filter, $wp_actions, $wp_current_filter, $merged_filters;


第一个$wp_filter是全局Array,其中将所有过滤器名称作为子数组保存。然后,这些子数组中的每个子数组都包含更多的子数组,这些子数组是在优先级数组下召唤的回调。

深入了解

因此,当调用execute函数时,WordPress会搜索这些全局变量具有该名称的键的数组。然后,附加的回调将在优先级之后获得优先级。唯一发生在前面的是附加到all过滤器的回调。

使用add_actionadd_filter添加回调时,WordPress首先会计算一个“唯一” ID,以不覆盖已连接的回调。 br />
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);


然后将回调添加到global $wp_filter堆栈中:

$wp_filter[ $tag ][ $priority ][ $idx ] = array(
    'function'      => $function_to_add,
    'accepted_args' => $accepted_args
);


如您所见,主子数组是$tag(或动作/过滤器名称),然后在特定优先级下召集所有内容,然后将“唯一”回调/ ID字符串用作键。

稍​​后,当过滤器被获取时被调用-与$tag / action- / filter-name一起发生-搜索数组并调用回调。因为它使用的是call_user_func_array,所以连接多少个参数并不重要。 WordPress会自行解决。

foreach ( (array) current( $wp_filter[ $tag ] ) as $the_ )
{
    call_user_func_array(
        $the_['function'], 
        array_slice(
            $args, 
            0, 
            (int) $the_['accepted_args']
        )
    );
}


评论


不要忘记,在进行回调时,它会使用“优先级”命令在同一钩子上执行多个回调,“优先级”是(可选)使用add_action()和apply_filters()设置的,默认值为10。

–汤姆·俄格(Tom Auger)
13年8月13日在20:28

@TomAuger请随时在答案中添加任何其他注释和修改。

– kaiser
13年8月13日在20:54

#2 楼

挂钩包含在WordPress核心文件和某些父主题文件中。它们使您能够在文件中的特定位置挂接内容。

示例是WordPress中的wp_head挂接。您可以在子主题中使用此挂钩在该位置添加内容'

示例:

add_action('wp_head', 'add_content_to_head');
function add_content_to_head() {
echo 'Your Content';
}


一些高级主题还包括动作挂钩您可以在儿童主题中使用它来执行相同的操作。这是一个可视化地图,其中包括所有动作挂钩及其在Genesis主题框架中输出内容的位置。

示例:

add_action('genesis_header', 'add_content_to_header');
function add_content_to_header() {
echo 'Your Content';
}


这是在Genesis主题框架中打开header.php文件时的外观:

do_action( 'genesis_header' );


以下是可以以多种方式使用的WordPress钩子列表。

过滤器使您能够修改现有功能的输出,并且包含在WordPress核心文件和某些父主题框架(如Genesis)中。

以下是列表可以与Genesis Design Framework一起使用的过滤器

这里是WordPress中包含的过滤器的列表

这里是如何在Genesis这样的主题框架中使用过滤器的示例:

add_filter( 'comment_author_says_text', 'custom_comment_author_says_text' );
function custom_comment_author_says_text() {
return 'author says';
}


以上代码可用于子主题中,以修改作者在评论中所说的文字。它适用于任何主题。

这是另一个将摘录长度自定义为50个单词的示例:

add_filter( 'excerpt_length', 'change_excerpt_length' );
function change_excerpt_length($length) {
return 50; 
}


您会找到the_excerpt ()函数位于wp-includes / post-template.php文件中。

外观如下:

  function the_excerpt() {
        echo apply_filters('the_excerpt', get_the_excerpt());
}


您还可以使用插件中的钩子和过滤器可以做完全相同的事情,并且在更新父主题或WordPress时代码不会丢失。

基本上,钩子和过滤器使您可以自定义和修改两个WordPress和您的父主题,而无需编辑核心WordPress文件或父主题文件。

当父主题框架包括挂钩和过滤器时,自定义子主题非常容易,因为您无需编辑父主题模板文件。这样,您也可以安全地更改主题。

评论


这是对钩子和过滤器的一个很好的总体概述,但是恐怕完全错过了OP的问题,即关于钩子如何工作以及WordPress如何创建,存储和处理它们的内部信息。好答案;您可能应该链接到WP网站上的教程。

–汤姆·俄格(Tom Auger)
13年8月14日在14:11

好吧,我将其删除。我的坏处是我应该更好地阅读该问题,但认为如果初学者了解基本知识,那么已经给出的答案将更易于初学者理解。

–布拉德·道尔顿(Brad Dalton)
13年8月14日在16:31

布拉德,我未删除它,因为我认为在此也有该信息可能很有用。如果您不同意,请在此处提及/联系我,然后我将其删除。

– kaiser
2014年3月20日10:50