add_action()とadd_filter()の違いと使い分け【WordPress】

WordPress

こんにちは!コーダーのゆうしです。

WordPressの functions.php を書いていると、add_action() と add_filter() の両方が出てきます。「なんとなく使っているけど、どう違うのかよくわかっていない」という方も多いのではないでしょうか。

この2つはどちらもWordPressのフックシステムを使う関数ですが、役割が明確に違います。今回はその違いと使い分けの基準を、コード例を交えて解説します。

そもそも「フック」とは

WordPressはページを表示するまでの処理の中に、あらかじめ「ここで外部から処理を差し込めますよ」という場所をたくさん用意しています。この場所のことをフックと呼びます。

フックには2種類あります。

  • アクションフック:ある処理のタイミングで「何かを実行する」場所
  • フィルターフック:データが使われる前に「値を加工して返す」場所

add_action() はアクションフックに、add_filter() はフィルターフックに自分の関数を登録するための関数です。

add_action():タイミングで「処理を実行」する

add_action() は、WordPressの処理の特定のタイミングで自分の関数を呼び出したいときに使います。スクリプトの読み込み、カスタム投稿タイプの登録、フッターへのHTML出力など「何かをする」系の処理がここに当たります。

コールバック関数は処理を実行するだけでよく、値を返す必要はありません

// functions.php

// wp_enqueue_scripts のタイミングでCSSを読み込む
function my_enqueue_styles() {
  wp_enqueue_style(
    'my-style',
    get_stylesheet_uri()
  );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );

上の例では、WordPressがスクリプト・スタイルを読み込むタイミング(wp_enqueue_scripts)に my_enqueue_styles() 関数を割り込ませています。関数の中で return は不要です。

add_filter():データを「加工して返す」

add_filter() は、WordPressが何らかのデータを使う直前に、その値を加工したいときに使います。投稿タイトルの文字列を変える、抜粋の文字数を変える、クエリの引数を差し替えるなどが典型例です。

コールバック関数は引数で値を受け取り、加工したうえで必ず return する必要があります。returnしないと、その値が null(もしくは空)になってしまい、表示が消えるなどの問題が起きます。

// functions.php

// 抜粋の文字数を80文字に変更する
function my_excerpt_length( $length ) {
  return 80;
}
add_filter( 'excerpt_length', 'my_excerpt_length' );

excerpt_length フィルターは抜粋の文字数(デフォルト55)をフィルタリングするためのフックです。コールバック関数の引数 $length に現在の文字数が渡されてくるので、それを加工して(またはそのまま別の値で)return します。

2つの一番の違いは「returnするかどうか」

add_action()add_filter()
役割処理を実行する値を加工して返す
コールバックのreturn不要必須
内部の発火関数do_action()apply_filters()
典型的な用途スクリプト読み込み、投稿タイプ登録、HTML出力タイトル・抜粋の加工、クエリ引数の変更

💡 実は内部的には add_action() は add_filter() のエイリアスです。WordPressのソースを見ると add_action() の中身は return add_filter() を呼び出しているだけです。ただし用途の意図を明確にするために、アクションには add_action()、フィルターには add_filter() を使い分けるのがベストプラクティスです。

第3引数(priority)と第4引数(accepted_args)

どちらの関数も第3・第4引数を持っています。省略できますが、知っておくと実務で役立ちます。

add_action( $hook, $callback, $priority, $accepted_args );
add_filter( $hook, $callback, $priority, $accepted_args );

第3引数:$priority(優先順位)

同じフックに複数の関数が登録されているとき、実行される順番を制御します。デフォルトは 10 で、数値が小さいほど先に実行されます。同じ数値の場合は登録された順に実行されます。

// priority 5 → 先に実行される
add_filter( 'the_title', 'my_title_prefix', 5 );

// priority 20 → 後から実行される
add_filter( 'the_title', 'my_title_suffix', 20 );

第4引数:$accepted_args(受け取る引数の数)

コールバック関数が受け取る引数の数を指定します。デフォルトは 1 です。フックによっては複数の引数が渡されることがあり、2つ目以降の引数も使いたい場合はここで数を指定する必要があります。

たとえば save_post アクションは投稿ID・投稿オブジェクト・更新かどうかの3つの引数を渡します。これら全部を受け取りたい場合は accepted_args に 3 を指定します。

// save_post は do_action( 'save_post', $post_ID, $post, $update ) で発火する
function my_save_post( $post_id, $post, $update ) {
  if ( $update ) {
    // 更新時だけ処理する
  }
}
add_action( 'save_post', 'my_save_post', 10, 3 );

躓きやすいポイント

add_filter()でreturnを書き忘れる

フィルターでよくやりがちなミスです。コールバック内で処理を書いたのに return を忘れると、その値が消えてしまいます。

 NG 

function my_excerpt_length( $length ) {
  $length = 80;
  // returnがないので値が消える → 抜粋が表示されなくなる
}
add_filter( 'excerpt_length', 'my_excerpt_length' );

 OK 

function my_excerpt_length( $length ) {
  return 80; // 必ずreturnする
}
add_filter( 'excerpt_length', 'my_excerpt_length' );

accepted_argsを指定せずに複数の引数を受け取ろうとする

デフォルトの accepted_args = 1 のままだと、フックが複数の引数を渡してきても2つ目以降は受け取れません。必要な引数の数を第4引数に明示してください。

 NG 

function my_save_post( $post_id, $post, $update ) {
  // $post と $update は受け取れないまま
}
add_action( 'save_post', 'my_save_post' ); // accepted_argsが1のまま

 OK 

function my_save_post( $post_id, $post, $update ) {
  // 3つ全部受け取れる
}
add_action( 'save_post', 'my_save_post', 10, 3 );

まとめ

使い分けのポイントを一言でまとめると「何かをするなら add_action()、値を加工して返すなら add_filter()」です。

  • add_action() はコールバックで処理を実行する。returnは不要
  • add_filter() はコールバックで値を加工してreturnする。returnを忘れると値が消える
  • 第3引数で実行順序、第4引数で受け取る引数の数を指定できる

フックの仕組みを理解しておくと functions.php でできることの幅が一気に広がります。ご不明な点やコーディングのご依頼はお問い合わせからお気軽にどうぞ。

タイトルとURLをコピーしました