結論
優先度($priority)は、数値が小さいほど先に実行される整数で、省略すると 10 です。決め方の基本は次の3つだけです。
- 他のコードと関係なければ、省略(10)でよい。
- 他のコードの前に何かしたいなら、それより小さい数(1〜9)。
- 他のコードの後で上書き・結果の確認をしたいなら、それより大きい数(11〜99、最後に確実に動かしたいなら大きな値)。
大切なのは「何の前後に動かしたいか」を先に決め、基準となるコールバックの優先度を has_action() / has_filter() で調べてから数値を選ぶことです。
原因・仕組み
WordPress は、1つのフックに登録されたコールバックを、優先度の小さい順に実行します。同じ優先度の中では登録した順です(公式の add_action() リファレンスにも同じ説明があります)。
注意したいのは、優先度が「絶対的な時刻」ではなく、「そのフックの中での相対的な並び順」でしかない点です。だから、100 を指定しても、他のプラグインが 999 を指定していれば、そちらが後です。
手順(サンプルコード)
1. 実行順を確認する
add_action( 'demo', function () { echo 'A'; } ); // 10(省略)
add_action( 'demo', function () { echo 'B'; } ); // 10(Aの後)
add_action( 'demo', function () { echo 'C'; }, 1 ); // 1
add_action( 'demo', function () { echo 'D'; }, PHP_INT_MAX );
add_action( 'demo', function () { echo 'E'; }, -5 ); // 負の値も使える
do_action( 'demo' );
// E > C > A > B > D の順
2. フィルターの結果を後から上書きする
add_filter( 'the_demo', function ( $v ) { return $v . '[theme10]'; } );
add_filter( 'the_demo', function ( $v ) { return $v . '[plugin99]'; }, 99 );
add_filter( 'the_demo', function ( $v ) { return $v . '[early5]'; }, 5 );
echo apply_filters( 'the_demo', 'x' );
// x[early5][theme10][plugin99]
フィルターは前のコールバックの戻り値が次の入力になります。自分の処理の前に何が済んでいるかで、受け取る値が変わります。
3. 基準の優先度を調べる
foreach ( array( 'wpautop', 'do_shortcode', 'wp_filter_content_tags', 'convert_smilies' ) as $f ) {
echo $f . ' => ' . var_export( has_filter( 'the_content', $f ), true ) . "n";
}
動作確認(検証環境と結果)
WordPress 7.1.2(ja)、PHP 8.2.12 の CLI 環境で実行しました。
- 手順1:
E(-5) > C(1) > A(10) > B(10) > D(PHP_INT_MAX)の順で実行された(負の値も有効、同じ優先度は登録順)。 - 手順2:
x[early5][theme10][plugin99]。 - 手順3:
the_contentの標準値は、wpautopが 10、do_shortcodeが 11、wp_filter_content_tagsが 12、convert_smiliesが 20、capital_P_dangitが 11 だった(この環境のコアでの値。バージョンで変わる可能性があるため、必ず自分の環境でhas_filterを確認してください)。 - 実行中に同じフック・同じ優先度へ別のコールバックを追加した場合、その回では実行されなかった(1回目の実行は「first」のみ)。優先度 20 のように後ろの優先度に追加した場合は実行された。
検証ログは testsadd-action-priority-how-to-decide.md にあります。
add_action の優先度の決め方の注意点
- 「とりあえず 9999」は、他のコードが同じことをすると崩れます。目的が「他の処理の後」であれば、基準より 1 だけ大きい数にするのが、意図が伝わります。
the_contentでdo_shortcode(11)の前後どちらで処理するかで、ショートコードの展開前後の HTML を受け取るかが変わります。- 優先度は整数として扱われます。小数は使わず、整数だけを指定します(リファレンスの型も int です)。
add_action の優先度の決め方でよくあるミス
wpautop(10)より前に整形したいのに、10 のまま登録して、順序が登録順任せになる。- 優先度を変えて登録したのに、
remove_action側で優先度を合わせていない(remove_action() の使い方|説明・引数・注意点参照)。 - 上書きしたいだけなのに、非常に大きな数を使い、後から他のプラグインと競合する。
- アクションの実行中に、同じ優先度へ追加して「実行されない」と悩む。
add_action の優先度の決め方のチェックリスト
- 「何の前、何の後」に動かしたいか、言葉で書けるか
- 基準のコールバックの優先度を
has_filter/has_actionで調べたか - 数値を、基準の前後を示す最小の変更にしているか
- 実行順を、
error_logやテストで確認したか - 削除処理の優先度が、登録と一致しているか
add_action の優先度の決め方のFAQ(よくある質問)
Q. 優先度の上限はありますか?
A. 実務では PHP の整数の範囲です。PHP_INT_MAX も使えます。
Q. 同じ優先度のコールバックを確実に先にしたいときは?
A. 優先度をずらすのが確実です。登録順は、読み込み順に依存するため不安定です。
Q. アクションでも優先度は同じ意味ですか?
A. 同じです。add_action は add_filter と同じ仕組みで、戻り値を使わないだけです。
筆者の見解(add_action の優先度の決め方)
優先度は「数字の大きさを競うもの」ではなく、「どのコードの隣に置くか」を表すものだと考えます。迷ったときは、まず 10 のまま動かし、順序が問題になったときだけ基準を調べて決める方が、後から読みやすいコードになると思います。
add_action の優先度の決め方の関連項目
- add_action() の使い方|説明・引数・注意点
- add_filter() の使い方|説明・引数・注意点
- remove_action() の使い方|説明・引数・注意点
- has_filter() の使い方|説明・引数・注意点
- apply_filters() の使い方|説明・引数・注意点
