如何获得WordPress的钩子/动作的运行顺序?

时间:2014-09-29 作者:T.Todua

按什么顺序add_action 执行挂钩?

i、 e。

init
wp_head
wp_footer
after_theme_setup 
etc...
???
???
???
编辑:我也发布了我的解决方案。

6 个回复
最合适的回答,由SO网友:birgire 整理而成

"E;数据数据数据"E;他不耐烦地哭了"E;没有粘土我就不能制砖"E;

Sherlock Holmes - The Adventure of the Copper Beeches

所以,让我们收集一些real data 从一个普通的WordPress 5.7.2安装中,只有一个文本小部件激活了Twenty12主题。

对于主页,请执行以下操作do_action / do_action_ref_array 按以下顺序进行呼叫(注销):

[0] => mu_plugin_loaded
[1] => muplugins_loaded
[2] => registered_taxonomy
[3] => registered_taxonomy
[4] => registered_taxonomy
[5] => registered_taxonomy
[6] => registered_taxonomy
[7] => registered_post_type
[8] => registered_post_type
[9] => registered_post_type
[10] => registered_post_type
[11] => registered_post_type
[12] => registered_post_type
[13] => registered_post_type
[14] => registered_post_type
[15] => registered_post_type
[16] => registered_post_type
[17] => plugins_loaded
[18] => sanitize_comment_cookies
[19] => wp_roles_init
[20] => setup_theme
[21] => unload_textdomain
[22] => load_textdomain
[23] => after_setup_theme
[24] => load_textdomain
[25] => load_textdomain
[26] => auth_cookie_malformed
[27] => set_current_user
[28] => init
[29] => registered_post_type
[30] => registered_post_type
[31] => registered_post_type
[32] => registered_post_type
[33] => registered_post_type
[34] => registered_post_type
[35] => registered_post_type
[36] => registered_post_type
[37] => registered_post_type
[38] => registered_post_type
[39] => registered_taxonomy
[40] => registered_taxonomy
[41] => registered_taxonomy
[42] => registered_taxonomy
[43] => registered_taxonomy
[44] => widgets_init
[45] => register_sidebar
[46] => register_sidebar
[47] => register_sidebar
[48] => wp_register_sidebar_widget
[49] => wp_register_sidebar_widget
[50] => wp_register_sidebar_widget
[51] => wp_register_sidebar_widget
[52] => wp_register_sidebar_widget
[53] => wp_register_sidebar_widget
[54] => wp_register_sidebar_widget
[55] => wp_register_sidebar_widget
[56] => wp_register_sidebar_widget
[57] => wp_register_sidebar_widget
[58] => wp_register_sidebar_widget
[59] => wp_register_sidebar_widget
[60] => wp_register_sidebar_widget
[61] => wp_register_sidebar_widget
[62] => wp_register_sidebar_widget
[63] => wp_register_sidebar_widget
[64] => wp_default_scripts
[65] => wp_register_sidebar_widget
[66] => wp_register_sidebar_widget
[67] => wp_register_sidebar_widget
[68] => wp_register_sidebar_widget
[69] => wp_register_sidebar_widget
[70] => wp_register_sidebar_widget
[71] => wp_register_sidebar_widget
[72] => wp_register_sidebar_widget
[73] => wp_register_sidebar_widget
[74] => wp_register_sidebar_widget
[75] => wp_register_sidebar_widget
[76] => wp_register_sidebar_widget
[77] => wp_register_sidebar_widget
[78] => wp_register_sidebar_widget
[79] => wp_register_sidebar_widget
[80] => wp_register_sidebar_widget
[81] => wp_register_sidebar_widget
[82] => wp_register_sidebar_widget
[83] => wp_register_sidebar_widget
[84] => wp_register_sidebar_widget
[85] => wp_register_sidebar_widget
[86] => wp_register_sidebar_widget
[87] => wp_register_sidebar_widget
[88] => wp_register_sidebar_widget
[89] => wp_register_sidebar_widget
[90] => wp_register_sidebar_widget
[91] => wp_register_sidebar_widget
[92] => wp_register_sidebar_widget
[93] => wp_register_sidebar_widget
[94] => wp_sitemaps_init
[95] => wp_loaded
[96] => parse_request
[97] => send_headers
[98] => parse_tax_query
[99] => parse_query
[100] => pre_get_posts
[101] => posts_selection
[102] => wp
[103] => template_redirect
[104] => get_header
[105] => wp_head
[106] => wp_enqueue_scripts
[107] => wp_default_styles
[108] => enqueue_block_assets
[109] => wp_print_styles
[110] => wp_print_scripts
[111] => wp_body_open
[112] => parse_tax_query
[113] => parse_query
[114] => pre_get_posts
[115] => parse_tax_query
[116] => posts_selection
[117] => parse_tax_query
[118] => parse_query
[119] => pre_get_posts
[120] => parse_tax_query
[121] => posts_selection
[122] => parse_tax_query
[123] => parse_query
[124] => pre_get_posts
[125] => parse_tax_query
[126] => posts_selection
[127] => parse_tax_query
[128] => parse_query
[129] => pre_get_posts
[130] => parse_tax_query
[131] => posts_selection
[132] => parse_term_query
[133] => pre_get_terms
[134] => loop_start
[135] => the_post
[136] => get_template_part_content
[137] => get_template_part
[138] => parse_comment_query
[139] => pre_get_comments
[140] => parse_comment_query
[141] => pre_get_comments
[142] => comment_form_comments_closed
[143] => loop_end
[144] => get_sidebar
[145] => dynamic_sidebar_before
[146] => dynamic_sidebar
[147] => dynamic_sidebar_after
[148] => get_footer
[149] => twentytwelve_credits
[150] => wp_footer
[151] => wp_print_footer_scripts
[152] => shutdown
使用must-use 插件:

add_action( \'all\', function ( $tag ) {
    static $hooks = array();
    // Only do_action / do_action_ref_array hooks.
    if ( did_action( $tag ) ) {
        $hooks[] = $tag;
    }
    if ( \'shutdown\' === $tag ) {
        print_r( $hooks );
    }
} );
它在最后一个可用的核心操作(关闭)中为当前页面打印收集的操作挂钩。

如果要检查操作的顺序以及每个操作的触发次数,则可以使用以下示例:

add_action ( \'shutdown\', function(){
    print_r ( $GLOBALS[\'wp_actions\'] );         
} );
或者没有显式全局变量:

add_action ( \'shutdown\', function() use ( &$wp_actions ) {
    print_r ( $wp_actions );      
} );
输出阵列的:

[mu_plugin_loaded] => 1
[muplugins_loaded] => 1
[registered_taxonomy] => 10
[registered_post_type] => 20
[plugins_loaded] => 1
[sanitize_comment_cookies] => 1
[wp_roles_init] => 1
[setup_theme] => 1
[unload_textdomain] => 1
[load_textdomain] => 3
[after_setup_theme] => 1
[auth_cookie_malformed] => 1
[set_current_user] => 1
[init] => 1
[widgets_init] => 1
[register_sidebar] => 3
[wp_register_sidebar_widget] => 45
[wp_default_scripts] => 1
[wp_sitemaps_init] => 1
[wp_loaded] => 1
[parse_request] => 1
[send_headers] => 1
[parse_tax_query] => 9
[parse_query] => 5
[pre_get_posts] => 5
[posts_selection] => 5
[wp] => 1
[template_redirect] => 1
[get_header] => 1
[wp_head] => 1
[wp_enqueue_scripts] => 1
[wp_default_styles] => 1
[enqueue_block_assets] => 1
[wp_print_styles] => 1
[wp_print_scripts] => 1
[wp_body_open] => 1
[parse_term_query] => 1
[pre_get_terms] => 1
[loop_start] => 1
[the_post] => 1
[get_template_part_content] => 1
[get_template_part] => 1
[parse_comment_query] => 2
[pre_get_comments] => 2
[comment_form_comments_closed] => 1
[loop_end] => 1
[get_sidebar] => 1
[dynamic_sidebar_before] => 1
[dynamic_sidebar] => 1
[dynamic_sidebar_after] => 1
[get_footer] => 1
[twentytwelve_credits] => 1
[wp_footer] => 1
[wp_print_footer_scripts] => 1
[shutdown] => 1
在那里我们可以用echo array_sum( $GLOBALS[\'wp_actions\'] );

下面是一个经过修饰的版本:

add_action ( \'shutdown\', function() {
    foreach ( $GLOBALS[\'wp_actions\'] as $action => $count ) {
        printf( \'%s (%d) <br/>\' . PHP_EOL, $action, $count );
    }
} );
或者没有显式全局变量:

add_action ( \'shutdown\', function() use ( &$wp_actions ) {
    foreach ( $wp_actions as $action => $count ) {
        printf( \'%s (%d) <br/>\' . PHP_EOL, $action, $count );
    }
} );
要获取以下列表:

mu_plugin_loaded (1)
muplugins_loaded (1)
registered_taxonomy (10)
registered_post_type (20)
plugins_loaded (1)
sanitize_comment_cookies (1)
wp_roles_init (1)
setup_theme (1)
unload_textdomain (1)
load_textdomain (3)
after_setup_theme (1)
auth_cookie_malformed (1)
set_current_user (1)
init (1)
widgets_init (1)
register_sidebar (3)
wp_register_sidebar_widget (45)
wp_default_scripts (1)
wp_sitemaps_init (1)
wp_loaded (1)
update_option (1)
update_option__transient_doing_cron (1)
updated_option (1)
set_transient_doing_cron (1)
setted_transient (1)
requests-requests.before_request (1)
requests-curl.before_request (1)
http_api_curl (1)
requests-curl.before_send (1)
requests-curl.after_send (1)
requests-curl.after_request (1)
requests-requests.before_parse (1)
http_api_debug (1)
parse_request (1)
send_headers (1)
parse_tax_query (9)
parse_query (5)
pre_get_posts (5)
posts_selection (5)
wp (1)
template_redirect (1)
get_header (1)
wp_head (1)
wp_enqueue_scripts (1)
wp_default_styles (1)
enqueue_block_assets (1)
wp_print_styles (1)
wp_print_scripts (1)
wp_body_open (1)
parse_term_query (1)
pre_get_terms (1)
loop_start (1)
the_post (1)
get_template_part_content (1)
get_template_part (1)
parse_comment_query (2)
pre_get_comments (2)
comment_form_comments_closed (1)
loop_end (1)
get_sidebar (1)
dynamic_sidebar_before (1)
dynamic_sidebar (1)
dynamic_sidebar_after (1)
get_footer (1)
twentytwelve_credits (1)
wp_footer (1)
wp_print_footer_scripts (1)
shutdown (1)
PS:你也应该看看Query Monitor 约翰·布莱克本的插件。(我与此插件无关)

SO网友:Robert hue

这是WordPress负载表

WordPress Load Chart

Source by @Rarst

SO网友:T.Todua

找到解决方案

谢谢伯吉尔的回答。我还要补充一点,muplugins_loaded 有时不会被解雇,所以我会用plugins_loaded 作为最早的钩子(但此时,用户授权尚未完成。如果要检查用户的授权,则init 是最早的)。。。

p、 美国有很多优秀的插件:

(1)Query Monitor - 您可以看到页面加载上发生的一切,即每个执行函数的持续时间等等(查看插件页面上的所有屏幕截图):

enter image description here

(2)WP-DEBUG-BAR + WP-DEBUG-SLOW-ACTIONS:
a)调试挂钩(actions) 在站点上运行列表
b)参见每个action (非功能):enter image description here

SO网友:Luca Reghellin

基本顺序也可以在官方文件中找到:

https://codex.wordpress.org/Plugin_API/Action_Reference

SO网友:Walf

没有两个请求是完全相同的。一种快速而肮脏(但非常准确)的方法是在do_action 中的函数wp-includes/plugin.php 其中记录$tag, e、 g.:

if (isset($some_get_or_post_trigger_var)) file_put_contents(ABSPATH . \'action.log\', "$tag\\n", FILE_APPEND);
你可能也想对apply_filters 同一文件中的函数。我还没有找到更好的方法来获得完整的时间序列。

SO网友:Kevin Leary

这与@birgire的答案类似,但它提供了一个很好的报告,可以为WordPress站点中的任何URL显示。您需要以管理员级别的用户身份登录,然后添加?wp-hooks 位于要测试的URL的末尾。

/**
* WordPress Hooks Reference
*
* Dump all action and filter hooks at the bottom of any page
* by adding ?wp-hooks onto the end of the URL while logged-in
* as an Administrator level user.
*/
function kevinlearynet_hooks_reference() {

    // Only shown for Administrator level users when ?list-wp-hooks is added to the URL
    $trigger = isset( $_GET[\'wp-hooks\'] ) && current_user_can( \'manage_options\' );
    if ( ! $trigger ) return;

    // Capture and sort filters and hooks
    $filters = array_keys( $GLOBALS[\'wp_filter\'] );
    sort( $filters );
    $actions = array_keys( $GLOBALS[\'wp_actions\'] );

    // Output rough template
    ob_start();
    ?>
    <section class="wp-hooks">
    <h1 class="wp-hooks__h1">WordPress Hooks Reference</h1>
    <div class="wp-hooks__lists">
    <div class="wp-hooks__col">
    <h2 class="wp-hooks__h2">Actions</h2>
    <?php foreach ( $actions as $hook ) : ?>
    <p class="wp-hooks__hook"><?php echo $hook; ?></p>
    <?php endforeach; ?>
    </div>
    <div class="wp-hooks__col">
    <h2 class="wp-hooks__h2">Filters</h2>
    <?php foreach ( $filters as $hook ) : ?>
    <p class="wp-hooks__hook"><?php echo $hook; ?></p>
    <?php endforeach; ?>
    </div>
    </div>
    </section>
    <style>
    .wp-hooks {
        padding: 30px;
        margin: 30px;
        border-radius: 4px;
        background: white;
        font-size: 16px;
        line-height: 1.4;
        height: 50vh;
        min-height: 500px;
        overflow-y: scroll;
    }
    .wp-hooks__lists {
        display: flex;
    }
    .wp-hooks__col {
        flex: 1;
        width: 50%;
    }
    .wp-hooks__h1 {
        margin: 0 0 20px;
    }
    .wp-hooks__h2 {
        line-height: 1;
        font-size: 18px;
        margin: 0 0 10px;
    }
    .wp-hooks__hook {
        padding: 0;
        margin: 0;
    }
    </style>
    <?php
    ob_end_flush();
}
add_action( \'shutdown\', \'kevinlearynet_hooks_reference\' );
输出如下所示:

enter image description here

这是我自己写的,下面是original source 供参考。这包括关于排序和功能背后的决策的更多细节。

结束

相关推荐

hooks & filters and variables

我是updating the codex page example for action hooks, 在游戏中完成一些可重用的功能(最初是针对这里的一些Q@WA)。但后来我遇到了一个以前没有意识到的问题:在挂接到一个函数以修改变量的输出后,我再也无法决定是要回显输出还是只返回它。The Problem: 我可以修改传递给do_action 用回调函数钩住。使用变量修改/添加的所有内容仅在回调函数中可用,但在do_action 在原始函数内部调用。很高兴:我将其修改为一个工作示例,因此您可以将其复制/粘贴