この記事は最後に更新してから1年以上経過しています。
説明
いつも何気なくfunctions.phpで使っているafter_setup_themeアクションやinitアクション。普段はあまり意識していなかったが、ふとしたことからどんな順番に呼び出されるのか気になってしまい、ちょっと調べてみた。アクション関数の登録は add_action関数で、そのアクション関数の呼び出しは do_action関数で行われる。'after_setup_theme'や'init'をパラメータとしてdo_action関数を調べれば、実行される順番は簡単に調べることができる。
答えはwp-settings.phpの中に
after_setup_themeやinitアクションを実行しているのは、wp-settings.phpである(WordPress 3.4.1現在)。この中では、投稿ページを表示する準備として、プラグインファイルの読み込み、テーマのfunctions.phpの読み込み、after_setup_themeアクションやinitアクションを順番に行っている。その流れを大ざっぱに整理すると、次のようになる。
主な動き | 備考 |
1.WordPressの初期化処理A | wp-includesの主要なコアファイルの読み込み。タクソノミーや投稿タイプの初期化など |
---|---|
2.各種プラグインの読み込み | アクティブかつ有効なプラグインのみ |
2.1 必須プラグインの読み込み | |
2.2 muplugins_loadedアクションの実行 | |
2.3 有効なプラグインの読み込み | |
2.4 wp-includes/pluggable.phpの読み込み | プラグインにより定義可能な関数の登録(詳しくは「プラグインで注意が必要な関数」を参照) |
2.5 plugins_loadedアクション実行 | |
3.WordPressの初期化処理B | $_RQUEST($_GET、$_POST)パラメータのクォート処理、$wp_the_query($wp_query)の生成など |
4.親テーマfunctions.php読み込み | 自テーマが子テーマの場合のみ |
5.自テーマfunctions.php読み込み | |
6.after_setup_themeアクション実行 | |
7.ユーザ情報の更新 | ログイン中か調べる( wp_get_current_user呼び出し) |
8.initアクション実行 | |
9.マルチサイトの状態チェック | マルチサイトの場合のみ |
10.wp_loadedアクション実行 |
以上のように、after_setup_themeアクションは自テーマfunctions.phpが呼び出された直後に実行され、その後でinitアクションが実行される。after_setup_themeアクションの実行は、initアクションの前ということだ。
initアクションから呼び出されるアクションに注意
自テーマでカスタマイズを行う際、after_setup_themeアクションとinitアクションのどちらで処理すべきなのかを悩むことがある(というか悩んでいる)。after_setup_themeアクションとinitアクションの切り分けするための指針が欲しいのだ。
まずはafter_setup_themeアクションとinitアクションの切り分けを考える前段階として、 add_action関数の機能について整理する。通常add_action関数を記述する場合、次のようにアクション名と対応する関数名を指定している。
この例のように第3パラメータは省略した場合、そのアクション関数のプライオリティは10として登録される。このプライオリティは、アクション関数の実行順に影響を与えるもので、数値が小さいほど優先して先に実行される仕組みになっている。このことを踏まえ、自テーマでafter_setup_theme、init、widgets_initアクション(自テーマでウィジェット拡張する場合に使用)のそれぞれをプライオリティを省略して登録。それぞれが呼び出された順番は次の通りである。
主な動き |
1.after_setup_themeアクション |
---|
2.widgets_initアクション |
3.initアクション |
ここでのポイントは、2と3のアクションの順番。2のwidgets_initアクションについて調べてみると、このアクションはwp_widgets_init関数(wp-includes/default-widgets.php)で実行されており、さらにwp_widgets_init関数自身はinitアクションとして登録されていた。
続いて、このwp_widgets_init関数と同じ様に、initアクションとして呼び出されるアクション関数がないか調べてみると、いくつかのアクション関数が登録・呼び出されることが確認できた。次の表は、それらアクション関数の一部である。
関数名 | プライオリティ | 備考 |
create_initial_post_types | 0 | 標準投稿タイプの登録 |
---|---|---|
create_initial_taxonomies | 0 | 標準タクソノミーの登録 |
wp_widgets_init | 1 | 標準ウィジェットの登録 |
smilies_init | 5 | 顔文字の登録 |
wp_cron | 10 | 疑似cron処理 |
kses_init | 10 | ksesの初期化 |
wp_schedule_update_checks | 10 | テーマやプラグインの更新確認 |
_wp_admin_bar_init | 10 | 管理バーの初期化(管理バーを表示する場合のみ) |
check_theme_switched | 99 | テーマの変更 |
fig.bにおいてwidgets_initアクション関数の後にinitアクション関数が実行した理由について整理すると、まず自テーマのinitアクション関数のプライオリティが10なのに対し、widgets_initアクションを実行するwp_widgets_init関数のプライオリティが1で登録されている。これにより、wp_widgets_init関数が先に呼び出され、そのwp_widgets_init関数の終了時にwidgets_initアクション関数が呼び出される。自テーマで登録したinitアクション関数は、この後、wp_schedule_update_checksまたは_wp_admin_bar_init関数の後で呼び出されるため、fig.bの示す順になったわけだ。
少し極端な例になってしまうが、自テーマでinitアクションを登録する際にプライオリティを0にすれば、widgets_initアクションよりも先に呼び出される。このような振る舞いはプライオリティ値の違いによるものであり、add_action関数によってアクション関数を登録する際は、その点をしっかり押さえておくべきだろう。
さて少し横道にそれてしまうが、create_initial_post_typesとcreate_initial_taxonomiesが気になる。これらはプライオリティが0で登録されており、最優先に実行されることを意味している。ただ、これらはfig.aの「1.WordPressの初期化処理A」にあるように、initアクションより前に実行済みである。確認のためwp-settings.phpをトレースしてみると、やはりそれぞれ2回ずつ実行されており、ちょっと気持ち悪い。
after_setup_themeアクションとinitアクションのどちらが最適?
2つアクションのどちらで対応するのがいいのかを考える上でポイントになるのは、先に説明したinitアクションの内容である。これらよりも先に処理しておかなければいけないことは、必然的にafter_setup_themeアクションで行わなければならない。また、after_setup_themeアクションとinitアクションの間では唯一ログイン中のユーザによるアクセスか調べている。ログイン中のユーザ情報を参照するような処理については、initアクションで対応するのが妥当だろう。
以上のことを踏まえ、まとめたのが次の表である。
アクション | 適していると思われる処理内容 |
after_setup_theme |
|
---|---|
init |
|
まだ完全に整理できれているわけではないが、概ねこんな感じの切り分けでいいだろう。
admin_initアクションはwp_loadedアクションの後
おまけ。管理者ページのカスタマイズする際、よく使用するアクションの1つにadmin_initアクションがある。このadmin_initアクションは、wp-admin/admin-ajax.php内に記述されており、initアクション内で実行されものではない。この実行順はwp_loadedアクションよりも後になるので、この点は押さえておこう。
リクエストデータのクォート処理のタイミング
おまけとなるが、「$_RQUEST($_GET、$_POST)パラメータのクォート処理」のタイミングも意識しておくべきだろう。WordPressでは、クエリーパラメータ$_RQUEST($_GET、$_POST)を強制的にクォート処理を行うようになっているが、そのタイミングはプラグインの読み込み後である。これは、プラグインの読み込み時はクォート処理前になるが、プラグインで登録したフィルターやアクション関数内はクォート処理前と後の両方の場合があるということ。これはちょっとむずいですね。
最終更新 : 2013年11月27日 10:24
関連
お勧め
add_shortcode(2018年5月27日 更新)
get_user_setting(2022年1月31日 更新)
have_posts(2018年5月27日 更新)
in_category(2018年5月27日 更新)
add_feed(2024年6月24日 更新)