WordPressのアクションフックの実行履歴を確認する


WordPressのコアやプラグインの動作タイミングに合わせて処理を実行させるアクションフックの実行順序が気になったので確認してみた。
公式サイトにも一応載っているが `アクションフックの完全（だといいのですが）なリスト`らしいので実際に使用している環境で見てみることに。
https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7

# アクションフックの仕組み
WordPressでは特定のタイミングの処理に合わせてユーザー（テーマ、プラグイン開発者）が処理を実行できるアクションフックというものがあります。
ユーザーは `add_action('action_name', '実行したい処理の関数名')` を使用することで処理を追加できます。
例：初期化アクションにタクソノミーを登録する処理を追加する
```php:functions.php
// 関数を追加する場合
function my_theme_register_taxonomies () {
    // do something
}
add_action( 'init', 'my_theme_register_taxonomies' );

// クロージャを使う場合
add_action( 'init', function() {
    // do something
});
```

これらは`do_action( 'action_name' )`関数によって呼び出され、実行されます。
なのでコレに小細工をすれば動作確認ができそうですね。

# `do_action`関数の編集
ソースコードを確認します。
https://core.trac.wordpress.org/browser/tags/4.9.1/src/wp-includes/plugin.php#L421

`do_action`実行時のアクションフックはない（無限ループになるので当然ですが）のでとりあえず確認できるよう`var_dump`で画面出力させてみました。

```php:plugin.php
function do_action($tag, $arg = '') {
  var_dump($tag);
  global $wp_filter, $wp_actions, $wp_current_filter;
  ...
```

見やすさを考えればファイル出力とかのほうがいいかも。
これで任意のページを表示すればアクション実行毎に画面出力されて動作が確認できます。

# 出力結果
## 画面ロード前
プラグインを色々いれているのでそのアクションフックも確認できます。
`post_type`は1種類しか追加していないのに何回も呼ばれている不思議。

```
string(16) "muplugins_loaded"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(14) "plugins_loaded"
string(12) "cptui_loaded"
string(21) "auth_cookie_malformed"
string(13) "wp_roles_init"
string(17) "auth_cookie_valid"
string(16) "set_current_user"
string(24) "sanitize_comment_cookies"
string(13) "wp_roles_init"
string(11) "setup_theme"
string(17) "unload_textdomain"
string(17) "after_setup_theme"
string(4) "init"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(12) "widgets_init"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(16) "register_sidebar"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(26) "wp_register_sidebar_widget"
string(23) "acf/include_field_types"
string(26) "acf/include_location_rules"
string(18) "acf/include_fields"
string(8) "acf/init"
string(20) "registered_post_type"
string(20) "registered_post_type"
string(8) "aws_init"
string(10) "cptui_init"
string(20) "registered_post_type"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(19) "registered_taxonomy"
string(25) "wpseo_double_clean_titles"
string(9) "wp_loaded"
string(15) "parse_tax_query"
string(15) "parse_tax_query"
string(15) "posts_selection"
string(17) "template_redirect"
string(14) "admin_bar_init"
string(19) "add_admin_bar_menus"
string(30) "get_template_part_parts/header"
<!DOCTYPE html>
```

## 画面ロード後
最後は`shutdown`で終わり。
```
</html>
string(8) "shutdown"
```

# 順序関係なく実行されたかを確認する
最後に`shutdown`フックがあるようなのでこのタイミングでアクション実行履歴、実行回数が格納されている `$wp_actions` 変数の中身を表示する処理を書けば、一覧が表示できそうです。

## shutdownフックに関数を追加する
デベロッパーツールのコンソールに表示してみます。

```php:functions.php
add_action('shutdown', function() {
  global $wp_actions;
  echo '<script>';
  foreach($wp_actions as $action => $count) {
    echo "console.log('%s: %d', '{$action}', {$count});";
  }
  echo '</script>';
});
```
## 実行結果
表示成功
![console.png](https://qiita-image-store.s3.amazonaws.com/0/107279/99f27b67-1d51-5536-4c99-2e275ef607cb.png)