Cum să obții secvența de execuție a hook-urilor/acțiunilor din WordPress?

29 sept. 2014, 10:59:23
Vizualizări: 58.6K
Voturi: 67

În ce ordine se execută hook-urile add_action?

de exemplu:

init
wp_head
wp_footer
after_theme_setup 
etc...
???
???
???



EDIT:

Mi-am postat și soluția.

1
Comentarii

notă, datele BACK-END vs FRONT-END diferă

T.Todua T.Todua
4 oct. 2024 20:45:24
Toate răspunsurile la întrebare 6
13
123

"Date! Date! Date!" strigă el nerăbdător. "Nu pot face cărămizi fără argilă."

Sherlock Holmes - Aventura de la Copper Beeches

Așadar, hai să adunăm niște date reale de la o instalare standard WordPress 5.7.2 cu tema TwentyTwelve activată și un singur widget Text.

Pentru pagina principală, următoarele apeluri do_action / do_action_ref_array sunt efectuate în următoarea ordine (utilizator deconectat):

[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

folosind plugin-ul must-use:

add_action( 'all', function ( $tag ) {
    static $hooks = array();
    // Doar hook-uri do_action / do_action_ref_array.
    if ( did_action( $tag ) ) {
        $hooks[] = $tag;
    }
    if ( 'shutdown' === $tag ) {
        print_r( $hooks );
    }
} );

care afișează hook-urile de acțiune colectate, pentru pagina curentă, în ultima acțiune disponibilă din nucleu (shutdown).

Dacă doriți să verificați ordinea acțiunilor și de câte ori este declanșată fiecare, puteți folosi de exemplu:

add_action ( 'shutdown', function(){
    print_r ( $GLOBALS['wp_actions'] );         
} );

sau fără globals explicite:

add_action ( 'shutdown', function() use ( &$wp_actions ) {
    print_r ( $wp_actions );      
} );

care afișează array-ul:

[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

unde putem obține numărul total cu echo array_sum( $GLOBALS['wp_actions'] );

Iată o versiune mai frumoasă:

add_action ( 'shutdown', function() {
    foreach ( $GLOBALS['wp_actions'] as $action => $count ) {
        printf( '%s (%d) <br/>' . PHP_EOL, $action, $count );
    }
} );

sau fără globals explicite:

add_action ( 'shutdown', function() use ( &$wp_actions ) {
    foreach ( $wp_actions as $action => $count ) {
        printf( '%s (%d) <br/>' . PHP_EOL, $action, $count );
    }
} );

pentru a obține următoarea listă:

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: Ar trebui să verificați și minunatul plugin Query Monitor de John Blackbourn. (Nu sunt asociat cu acest plugin)

29 sept. 2014 12:04:02
Comentarii

Foarte frumos într-adevăr!

jdm2112 jdm2112
19 mar. 2015 21:30:32

Mulțumesc că ai menționat Query Monitor. Pare a fi un plugin util în acest caz.

D.A.H D.A.H
16 oct. 2015 12:53:37

@kraftner mulțumesc pentru actualizare, întotdeauna am plănuit (dar am uitat) să fac legătura directă către povestea în sine ca sursă corectă, evident că abilitățile mele de detectiv Sherlock Holmes nu au fost grozave atunci ;-)

birgire birgire
1 mar. 2017 15:22:07

Mi-a plăcut citatul și am vrut să văd mai mult context. Și cum deja aveam linkul pentru mine, de ce să nu-l actualizez și aici. :)

kraftner kraftner
1 mar. 2017 16:22:28

Asta ar trebui să facă parte din codex, vorbesc serios.

Johansson Johansson
13 iul. 2017 19:54:45

ma bucur să aud că te-a ajutat @JackJohansson

birgire birgire
13 iul. 2017 21:22:13

Postare de peste 4 ani și încă utilă. Mulțumesc mult!

Sebastian Kaczmarek Sebastian Kaczmarek
5 feb. 2019 12:15:21

Aceasta nu obține exact secvența din cauza grupării după numele hook-ului.

Walf Walf
12 iul. 2021 06:28:28

@Walf Te rog să consulți răspunsul actualizat pentru WP 5.7.2 și mu-plugin.

birgire birgire
12 iul. 2021 13:49:56

Răspunsul tău actualizat este o îmbunătățire semnificativă. Cu toate acestea, este posibil să nu producă nicio ieșire dacă o eroare oprește execuția. Desigur, o eroare îți spune unde a avut loc, dar cunoașterea evenimentelor precedente poate fi extrem de utilă. De asemenea, utilizarea instrucțiunilor print/dump este probabil să interfereze cu cererea sau să fie anulată complet dacă se termină cererea prematur.

Walf Walf
13 iul. 2021 04:35:37

WordPress înregistrează cârligul (hook) de acțiune shutdown ca o funcție de închidere cu PHP register_shutdown_function( 'shutdown_action_hook' ), astfel încât va rula la final chiar dacă, de exemplu, un alt cârlig apelează exit(), declanșează o eroare cu trigger_error() sau aruncă o eroare neprinsă. Conform comentariilor din documentația PHP, ar trebui să ruleze și după expirarea timpului. Da, nu va afișa dacă fastcgi_finish_request o întrerupe, dar cred că s-ar putea înregistra în jurnal dacă afișarea este o problemă.

birgire birgire
13 iul. 2021 15:06:28

Încă util în 2022: mulțumesc!

Gas Gas
29 sept. 2022 12:50:15

Mă bucur să aud că încă este util @Gas

birgire birgire
29 sept. 2022 14:00:56
Arată celelalte 8 comentarii
3
28

Iată graficul de încărcare WordPress

WordPress Load Chart

Sursa de la @Rarst

29 sept. 2014 11:04:06
Comentarii

Adaugă cel puțin sursa, sau chiar mai bine: găsește o întrebare duplicat pentru aceasta.

fuxia fuxia
29 sept. 2014 11:36:59

De fapt, nu știam de unde am obținut-o. Aveam această imagine salvată pe PC. Altfel aș fi făcut asta.

Robert hue Robert hue
29 sept. 2014 11:43:44

Este publicată și pe pagina principală a lui Tom Mc Farlin: The WordPress Page Lifecycle -> https://tommcfarlin.com/wordpress-page-lifecycle/

D.A.H D.A.H
16 oct. 2015 13:05:24
0

Soluție găsită!

Mulțumesc @birgire pentru răspunsul frumos. Voi adăuga că muplugins_loaded uneori nu se declanșează, așa că voi folosi plugins_loaded ca primul hook (dar în acel moment, autorizarea utilizatorului nu este încă făcută. Dacă doriți să verificați autorizarea utilizatorului, atunci init este cel mai devreme pentru asta)...

p.s. există plugin-uri excelente:

1) Query Monitor - Puteți vedea tot ce se întâmplă la încărcarea paginii, adică durata fiecărei funcții executate și multe altele (vizualizați toate capturile de ecran pe pagina plugin-ului):

Monitorizare interogări în timp real

2) WP-DEBUG-BAR + WP-DEBUG-SLOW-ACTIONS:
a) listă de depanare a hook-urilor (acțiuni) rulate pe site-ul tău.
b) Vezi durata fiecărei acțiuni (nu funcție): Bara de depanare WordPress

23 dec. 2017 22:22:50
0

Secvența de bază poate fi găsită și în documentația oficială:

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

28 mai 2018 17:57:16
0

Acest lucru este similar cu răspunsul lui @birgire, dar oferă un raport detaliat care poate fi afișat pentru orice URL într-un site WordPress. Va trebui să fii autentificat ca utilizator cu nivel de Administrator, apoi adaugă ?wp-hooks la sfârșitul URL-ului pe care dorești să-l testezi.

/**
* Referință pentru Hook-uri WordPress
*
* Afișează toate hook-urile de acțiune și filtrare în partea de jos a oricărei pagini
* prin adăugarea parametrului ?wp-hooks la URL cât timp ești autentificat
* ca utilizator cu nivel de Administrator.
*/
function kevinlearynet_hooks_reference() {

    // Se afișează doar pentru administratori când se adaugă ?wp-hooks la URL
    $trigger = isset( $_GET['wp-hooks'] ) && current_user_can( 'manage_options' );
    if ( ! $trigger ) return;

    // Captură și sortează filtrele și hook-urile
    $filters = array_keys( $GLOBALS['wp_filter'] );
    sort( $filters );
    $actions = array_keys( $GLOBALS['wp_actions'] );

    // Generează șablonul de afișare
    ob_start();
    ?>
    <section class="wp-hooks">
    <h1 class="wp-hooks__h1">Referință Hook-uri WordPress</h1>
    <div class="wp-hooks__lists">
    <div class="wp-hooks__col">
    <h2 class="wp-hooks__h2">Acțiuni</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">Filtre</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' );

Ieșirea arată astfel:

Previzualizare referință hook-uri WordPress

Am scris despre asta pe blogul meu, așa că iată sursa originală pentru referință. Aceasta include mai multe detalii despre deciziile din spatele sortării și funcționalității.

5 mai 2020 18:44:11
0

Nu există două cereri exact la fel. O metodă rapidă și simplă, dar foarte precisă pentru a afla ce se întâmplă, este să adăugați temporar linii la începutul funcțiilor do_action și do_action_ref_array din wp-includes/plugin.php pentru a înregistra fiecare hook, de exemplu:

if (isset($some_trigger_from_get_post_head_etc)) file_put_contents(ABSPATH . 'hooks.log', "$hook_name\n", FILE_APPEND);

Ați putea face același lucru și pentru funcțiile apply_filters și apply_filters_ref_array din același fișier. Nu am găsit o metodă mai bună pentru a obține secvența completă și cronologică, inclusiv hook-urile care se declanșează înainte ca plugin-urile must-use să se încarce și după shutdown.

24 nov. 2017 10:48:48