PHPのフックってなんぞ（フィルターフック編）

[前回の記事](https://qiita.com/nyopono/items/2f87fd5a7c3996250c92)の続きで今回はフィルターフックについてまとめていきます。

※参考記事
・[Web 制作リファレンス （＋α）](https://www.webdesignleaves.com/pr/wp/wp_func_hook.html)
・[WordPress フィルターフックの使い方を理解する](https://shu-sait.com/wordpress-filter-hook-tukaikata/)

# フィルターフックとは
[こちらの記事](https://www.webdesignleaves.com/pr/wp/wp_func_hook.html)から抜粋

>WordPressの処理の途中で、出力する内容をカスタマイズしたい場合に使われる仕組み

例えばWordPressでブログを設営していたとして、<font color="blue">記事タイトルの頭に「■」という記号をつけたくなった</font>とします。
一つ一つに「■」を書き足していくのは非常に手間なので、こういうシーンで役に立つのがフィルターフックというわけです。

「記事タイトルを出力する部分」を**フック**で引っ掛けてきて、<font color="blue">「■を書き足す」</font>と設定しておいた**フィルター**に通すことで、内容を加工して出力することができます。

## フィルターフックの実行方法

工程的にはざっくり以下の通りです。
**(1)add_filter関数でフィルターの設定を行う**
**(2)apply_filters関数を使ってフィルターを実行する**


実行したいプログラムの登録と実行を別々の関数で行うという部分はアクションフックと似ています。
.


#### (1)[add_filter関数](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/add_filter)でフィルターの設定を行う

まずは**関数の書き方**からです。

```php
<?php add_filter( 
$tag, //第一引数(必須）:フィルターフックの名前（カスタマイズしたい"元の内容"の名前）
$function_to_add, //第二引数(必須）:フィルターが適用されたときに呼び出される関数名
$priority, //第三引数(任意）:関数実行の優先順位
$accepted_args //第四引数(任意）:フックした関数が受け入れられる引数の数
); ?>
```

任意箇所の解説は省略して、第一引数と第二引数について触れます。

**第一引数**はフィルターフックの名前とありますが、これはアクションフックでいう
「フックで引っ掛けるタイミング」にあたる部分だと解釈しています。

繰り返しになりますが、フィルターフックは元の内容を加工して出力することが目的なので、
その「元の内容」にあたる部分をここで引っ張ってきているイメージです。

また、第一引数は**①独自で作成するオリジナルのもの、②WordPressがあらかじめ設置しているもの**の２種類があり、
②の場合はWordPress公式指定の名前を、①の場合は自身で設定した関数名などを記載します。
.

**第二引数**はフックする関数名を任意の名前で記載します。
これも個人的にわかりにくいので、「使用するフィルターの名前」と捉えていますが、
厳密にいうと**フィルターが適用されたときに呼び出される関数の名前**という表現が正しいようです。


なお、ここでは関数名しか書いていませんが、アクションフックと同じく、
この後で第二引数で指定した関数名に対し、function関数を使って
具体的なフィルターの設定を行うため、ここでは関数名を呼び出してるだけという認識でOKです。
.

次に**関数を書く上での注意事項**です。

アクションフックとは異なる重要な部分ですが、フィルターフックでは、
フィルターの設定時において、<font color=red>コールバックの記述（return文）が別途必要になります。</font>

詳しくは、後の[(2)apply_filters関数を使ってフィルターを実行する](####(2)apply_filters関数を使ってフィルターを実行する)で触れますが、
簡単にいうと、フィルターを実行する際に、**パラメーター**を指定する必要があるためです。

ここでいうパラメーターとは、**フィルターで加工した結果を入れておくための入れ物**みたいなものです。
つまり、add_filter関数でフィルターの設定を行う段階で、上述のパラメーターに対して、
設定した内容の**戻り値（結果）を返す**よう記述していく流れとなります。

なお、戻り値がどのような内容なのかについては、[WordPress Codex](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/add_filter)に記述があります。

>add_filter関数の戻り値
>フィルターフックに関数を登録できると true を、そうでなければ false を返します。

.
.
ここまでの内容をまとめると、以下のような記述方法になります。

```php
<? php
add_filter( フック名, コールバック関数名, 優先順位, 引数の数 );

function コールバック関数($value) {
  //フィルターが適用される際の処理をここに書く
  return $value;  //引数に受け取った値（$value）を加工して返すか変更後の値を返す
}

//（補足）；$valueの部分は任意の名前（ここではひとまずvalueにしているだけです）
```
.
ちなみここではわかりやいように別途function関数を準備して実行内容を記述していますが、
以下のように、無名関数を使ってadd_filter関数にひとまとめに記述することも可能です。

```php
<? php
add_filter('フック名', function($value){
    //フィルターが適用される際の処理をここに書く
    return $value;  //引数に受け取った値（$value）を加工して返すか変更後の値を返す
});
```
.
.

#### (2)[apply_filters関数](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/apply_filters)を使ってフィルターを実行する

まずは記述方法から見ていきます。

```php
<?php apply_filters( 
$tag,  //第一引数（必須）：フィルターフックの名前（add_filter関数の第一引数）
$value, //第二引数（必須）：$tag に登録されたフィルター関数が変更できる値
$var//第三引数（任意）：フィルター関数へ渡す追加の変数
); ?> 
```

第一引数はadd_filter関数の第一引数と同じですので、
ここでは第二引数の説明を含め、関数を書く上での注意点のみ以下にまとめておきます。

・[(1)add_filter関数でフィルターの設定を行う](####(1)add_filter関数でフィルターの設定を行う)でも触れた通り、第二引数には、
　**フィルターの設定結果（戻り値）を持っているパラメーター**を書きます。

・apply_filters関数の機能は「フィルターフックに追加された関数を呼び出す」だけなので、
　フィルターフックを実行する場合は**コールバック文**も併せて記述する必要があります。

.
ここまでの内容をまとめると、以下のような記述方法になります。

```php
<? php
return apply_filters('フック名', $value);

//（補足）；$valueの部分は任意の名前（ここではひとまずvalueにしているだけです）
```
.
.

## フィルターフックの記述例（練習）

ここまでで書き方のルールはザックリ抑えられたので、実際に練習してみます。
今回は②WordPressがあらかじめ設置しているフィルターフックである[the_title](https://developer.wordpress.org/reference/hooks/the_title/)を使用します。


事前に書く順番を整理しておきます。

**1. add_filter関数を記述してフィルターを設定する**
**2. apply_filters関数を記述してフィルターを実行する**
.

**1. add_filter関数を記述してフィルターを設定する**

```function.php
<? php
add_filter('the_title', function($title){
    return '■'.$title; //文字列連結でタイトルの前に「■」をつけるように設定
});
}
```
無名関数を使用して投稿タイトルの前に「■」をつけるように設定しています。
なお、パラメーターの名前は[WordPressCodex](https://developer.wordpress.org/reference/hooks/the_title/)に「$title」と書くよう指定されているため、こちらのルールに則っています。
.

**2. apply_filters関数を記述してフィルターを実行する**

実は②WordPressがあらかじめ設置しているフィルターフックを使用する場合、
**WordPressのコアファイル（wp-includes/post-template.php）に
apply_filters関数が既に記述されています。**

中身は以下の通りです。

```php
// wp-includes/post-template.php
function get_the_title( $post = 0 ) {
return apply_filters( 'the_title', $title, $id );
}
```

内容的には**投稿タイトルを取得（get_the_title）する際にフィルターフックを実行し、加工された内容をタイトルとして出力する**というイメージですかね。

これでWordPress上の全ての投稿タイトルの頭に「■」が挿入されます。

.

# おわりに
とりあえず概要から把握するために記事を書きましたが、コアファイルの部分など、
潜っていくとかなり深そうなので、ここで止めておきます。

まあ、内容を加工するのに使うんだなあ程度で今はヨシとしよう。。