このページではワードプレスの「フック」について解説します。
個人的にはワードプレスの開発において特に重要なのが「クエリー」「テンプレート」「フック」の3つだと思います。この1つが「フック」ですね。
「フック」を理解すればテーマ開発やプラグイン開発の自由度が一気に高まります。しかし「フック」は特にプログラミングやワードプレスでの開発の初心者の方には難しい仕組みだと思います。
このページでは、この「フック」を初心者の方にも分かりやすく、イメージが湧きやすいように解説していきたいと思います。
Contents
フックとは
プログラミング一般においてのフックとは下記のようなものになります。
フック(Hook)は、プログラム中の特定の箇所に、利用者が独自の処理を追加できるようにする仕組みである。また、フックを利用して独自の処理を追加することを「フックする」という。 処理を追加できる箇所は、元のプログラムの開発者によって、あらかじめ決められている。初期化処理や入出力処理などの直前・直後が対象としてよく選ばれる。
主に元のプログラムに対する機能追加・拡張やカスタマイズの手段として使われるほか、デバッグのための情報収集にも有効である。
引用元:Wikipedia(フック)
端的に説明されている良い説明文なのですが、フックをご存知無い方にとってはちょっと難しいかもしれません。まずはイメージが湧くように図を用いて解説していきたいと思います。
ワードプレスのプログラムの中には下図のようなフックがたくさん仕込まれています。
フックにはそれぞれ「名前」がつけられています。図では「フック1」と「フック2」と名付けています。
このフックに対し、ワードプレスのプログラムの中で下記のような処理を行うことが可能です。
- フックに関数をフックする
(フックした関数を取り除く事も可能) - フックにフックされた関数を実行する
1つ目の処理は「フックに関数をフックする」処理です。フックするとは、フックに関数を引っかける(登録する)ことを言います。図で表すと下のようになります。図では引っかかっているのは輪ゴムですが、実際には関数を引っかけることになります。
一つのフックに複数の関数をフックする事も可能です。
2つ目の処理は「フックにフックされた関数を実行する」処理です。フックに引っかかっている関数を実行するイメージですね。複数の関数がフックされている場合は、それらの全関数を順番に実行することになります。
この「フックにフックされた関数を実行する」処理は、元々のワードプレス本体に既に仕込まれています。様々なタイミングでこの処理が行われるようにワードプレスが作られています。
ですので、イメージとしては、フックに関数を引っ掛けておけば、後はワードプレスがその関数を勝手に実行してくれる感じです。
例えばワードプレスの起動時にはテーマのセットアップが行われます。このテーマのセットアップ開始前のタイミングで 「setup_theme」という名前のフックにフックされた関数群を実行するようにワードプレスは作成されています。
またテーマのセットアップ完了後のタイミングで 「after_setup_theme」という名前のフックにフックされた関数群を実行するようになっています。
実際にソースコードも見てみましょう。上記の2つのフックにフックされた関数を実行する記述が行われているのは「ワードプレスインストールフォルダ/wp-settings.php」の下記部分になります。
/**
* Fires before the theme is loaded.
*
* @since 2.6.0
*/
do_action( 'setup_theme' );
// Define the template related constants.
wp_templating_constants();
// Load the default text localization domain.
load_default_textdomain();
$locale = get_locale();
$locale_file = WP_LANG_DIR . "/$locale.php";
if ( ( 0 === validate_file( $locale ) ) && is_readable( $locale_file ) ) {
require( $locale_file );
}
unset( $locale_file );
/**
* WordPress Locale object for loading locale domain date and various strings.
*
* @global WP_Locale $wp_locale WordPress date and time locale object.
* @since 2.1.0
*/
$GLOBALS['wp_locale'] = new WP_Locale();
/**
* WordPress Locale Switcher object for switching locales.
*
* @since 4.7.0
*
* @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
*/
$GLOBALS['wp_locale_switcher'] = new WP_Locale_Switcher();
$GLOBALS['wp_locale_switcher']->init();
// Load the functions for the active theme, for both parent and child theme if applicable.
foreach ( wp_get_active_and_valid_themes() as $theme ) {
if ( file_exists( $theme . '/functions.php' ) ) {
include $theme . '/functions.php';
}
}
unset( $theme );
/**
* Fires after the theme is loaded.
*
* @since 3.0.0
*/
do_action( 'after_setup_theme' );
ここで、下記の2行が「フックにフックされた関数を実行する処理」になります。
do_action( 'setup_theme' );
do_action( 'after_setup_theme' );
この do_action 関数は、まさに「フックにフックされた関数を実行する」を行う関数です。引数に指定しているのが「フックの名前」です。「フックにフックされた関数を実行する処理」を行う関数は他にもあります。このあたりはフックの使い方で詳しく説明します。
ここまで説明してきたように「フックにフックされた関数を実行する」処理は既にワードプレスの動作の様々なタイミングで実行するように仕込まれています。
つまり、テーマ開発者やプラグイン開発者は、ワードプレス本体を変更しなくても、テーマやプラグイン側から「フックに関数をフックする」処理を実行してやれば、ワードプレスの動作の様々なタイミングに、独自の処理を割り込ませて実行することが可能になります。
例えば「after_setup_theme」フックに「myFunc_A」という関数をフックした場合、ワードプレスの起動時の処理の流れは下記のように変わります。
つまりテーマのセットアップ処理とワードプレスの初期化処理の間に独自の処理を割り込ませることができます。このようにフックを利用することで独自の処理を割り込ませ、ワードプレスの動きを制御することが可能になります。
あまり良くない例ですが、例えば myFunc_A 関数にメールを送信する処理を記述しておけば、ワードプレスが起動するたびにメールをワードプレスが自動的に送信してくれるようにすることもできます。
こんな感じで、ワードプレスは、例えばテーマやプラグインから関数をフックするだけでワードプレスを簡単にカスタマイズすることが可能なように作られています。
ここまでが、フックがどのようなものであるかの説明になります。イメージ湧いたでしょうか?ここまでの話をまとめておきます。
- ワードプレスには様々なフックが用意されている
- フックには下記を行うことが可能
- フックに関数をフックする
- フックにフックされた関数を実行する
- 「フックにフックされた関数を実行する」処理は、もともとのワードプレス本体の様々な箇所に仕込まれている
- フックに関数をフックすることで独自の処理を割り込ませて実行することが可能
ここまで「フックに関数をフックする」と「フックにフックされた関数を実行する」の2つの処理として説明してきましたが、特にテーマ開発やプラグイン開発の入門者が理解すべきは1つ目の処理である「フックに関数をフックする」です。
これは、前述の通り「フックにフックされた関数を実行する」処理はワードプレス本体にすでに仕込まれており、後は関数のフックさえしてやればワードプレスの動きを制御することができるためです。
ただし、どんなフックが存在するのか、どんな箇所にフックにフックされた関数が実行する仕組みが仕込まれているかを知らないとフックを最大限に利用することは不可能です。
そのため、2つ目の処理である「フックにフックされた関数を実行する」処理についても知っておいた方が良いです。
このページではこの辺りのことを踏まえて、「フックに関数をフックする」処理だけでなく「フックにフックされた関数を実行する」処理についても解説していきます。
フックの重要性
この「フック」はワードプレスでのテーマ開発やプラグイン開発においてフックは非常に重要です。この理由は下記の2つです。
- 開発(テーマやプラグインの開発)の自由度を安全に高められる
- カスタマイズが容易な親テーマが開発できる
スポンサーリンク
開発の自由度を安全に高められる
ワードプレス本体(ワードプレスを起動したり投稿データを取得したりする部分や管理画面を構成する部分)はワードプレス開発者によって開発され、度々アップデートが行われます。
ですので、ワードプレス本体を変更してしまうと変更部分がアップデートにより消えてしまう、アップデート自体が上手くできなくなる可能性もありますし、ワードプレス管理画面が開かなくなるような不具合が発生する可能性も高いです。
したがってワードプレス本体を変更するのはリスクが高いです。
しかしその一方で、ワードプレス本体の動きが制御できないと開発できるテーマやプラグインがかなり制限されてしまいます。例えばワードプレス起動時の動きや管理画面の動きを変更することができません。
これを解決してくれるのが「フック」です。ここまででも説明をしましたが、フックを利用すれば、ワードプレス本体のソースコードを変更することなく、ワードプレスの動きを制御すること(処理の追加)が可能です。
ですので、フックを利用することでテーマやプラグインの開発の自由度が大幅に広げることが可能になります。
カスタマイズが容易な親テーマが開発できる
「開発の自由度を安全に高められる」ためには、主に「フックに関数をフックする」処理を用います。
では「フックにフックされた関数を実行する」処理は自分で実装する必要がないかと言うと、そういう訳ではありません。
特にテーマ開発においては「フックにフックされた関数を実行する」処理を、自分のテーマ内のプログラムに仕込んでおくことは重要です。
例えば「フックにフックされた関数を実行する」処理が親テーマ内に仕込まれていれば、子テーマからは親テーマを変更せずに、そのフックに関数をフックするだけで自由度の高い子テーマの開発が可能になります。
また開発済みのテーマをカスタマイズする場合もフックに関数をフックするだけで安全にカスタマイズすることが可能です。
このようにフックを利用すれば、自分自身が開発するテーマのカスタマイズにも役立ちます。テーマを開発する場合は、カスタマイズが容易になるように、適切なタイミングで「フックにフックされた関数を実行する」処理を仕込んでおくことをオススメします。
フックの種類
それでは具体的にワードプレスのフックについて詳細を説明していきたいと思います。
ワードプレスのフックには2種類のフックが存在します。
- アクションフック
- フィルターフック
この2つの種類のフックについて説明していきます。
スポンサーリンク
アクションフック
アクションフックとは「ワードプレスの動きそのものを制御するためのフック」です。
ワードプレスには、ワードプレス起動時の動き、管理画面表示時の動き、記事投稿時の動き、などなどを制御するためのアクションフックが仕込まれています。
例えば分かりやすいのが投稿記事公開時の動きを制御するためのアクションフックです。このアクションフックには「publish_post」という名前が付けられています。
この「publish_post」というアクションフックに、メールを送信するような関数をフックさせれば、投稿記事公開時にワードプレスがメールを自動的に送信するように、ワードプレスの動きを制御することが可能です。
他にも様々なアクションフックがワードプレスには用意されています。イメージしやすいものをいくつかピックアップしてみました。
pre_get_posts
メインクエリーを変更するために用意されたアクションフックです。
このアクションフックにフックされた関数はメインクエリー発行前に実行されるため、フックする関数の中でメインクエリーを変更すれば、メインクエリー発行により取得できる投稿データを変更することが可能です。
投稿データの表示順を変更する例を下記ページで紹介していますので合わせて読んでいただけると理解が深まると思います。
ワードプレスで投稿記事の表示順を変更するこのアクションフックにフックされた関数は、「ワードプレスインストールフォルダ/wp-includes/class-wp-query.php」の下記で実行されます。
public function get_posts() {
global $wpdb;
$this->parse_query();
/* 〜略〜 */
do_action_ref_array( 'pre_get_posts', array( &$this ) );
// Shorthand.
$q = &$this->query_vars;
/* 〜略〜 */
do_action_ref_array
については後述します。
widgets_init
ウィジェット追加用に用意されたアクションフックです。
この widgets_init アクションフックにウィジェットを追加する関数をフックすれば、テーマに独自のウィジェットを追加することが可能です。
このアクションフックにフックされた関数は、「ワードプレスインストールフォルダ/wp-includes/widgets.php」の下記で実行されます。
function wp_widgets_init() {
if ( ! is_blog_installed() ) {
return;
}
register_widget( 'WP_Widget_Pages' );
register_widget( 'WP_Widget_Calendar' );
/* 〜略〜 */
/**
* Fires after all default WordPress widgets have been registered.
*
* @since 2.2.0
*/
do_action( 'widgets_init' );
}
after_setup_theme
テーマの設定や初期化等を行うためのアクションフックです。
テーマ読み込み後(つまりテーマの functions.php 読み込み後)、最初に実行されるアクションフックになります。
after_setup_themer アクションフックにフックされた関数が実行される場所は前述で紹介していますので、ここでは省略します。
publish_post
前述の通り、投稿記事公開時のワードプレスの動きを制御するためのアクションフックです。
publish_post アクションフックにフックされた関数が実行されるのは、「ワードプレスインストールフォルダ/wp-includes/post.php」の下記場所になります。
function wp_transition_post_status( $new_status, $old_status, $post ) {
/* 〜略〜 */
do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
}
この関数は投稿記事のステータスが変化した時に実行される関数であり、投稿記事公開時には、$new_status
が「publish」、$post->post_type
が「post」となるため、結果的に publish_post アクションフックにフックされた関数が実行されることになります。
同様に投稿記事のステータスが変化した時に実行されるアクションフックとしては trash_post(ゴミ箱に入れられた時に実行)などがあります。
その他のアクションフック
その他にも、非常にたくさんのアクションフックが様々な用途・タイミング用にワードプレスに仕込まれています。このアクションフックの一覧は下記ページで公開されています。
参考 アクションフック一覧WordPressCodex日本語版アクションフックの戻り値
アクションフックにフックされた関数は戻り値の返却は不可です。これはアクションフックがワードプレスの動きを制御するだけのものだからです。アクションを起こさせるだけなのがアクションフックです。
フィルターフック
フィルターフックは「データの加工を行うためのフック」です。”Filter” という英単語には「データを加工する」という意味がありますので、そこから来ている用語と考えるとイメージしやすいと思います。
データとは、具体的にはデータベース(MySQL)から読み込まれたデータもしくはデータベースに書き込むデータ(記事本文やタイトル、コメントなどなど)のことを指します。
なのでフィルターフックは、データベースから読み込んだデータを加工して表示する or データを加工してデータベースに書き込むためのフックと考えて良いです。
またフィルターフックはデータベースにアクセスする直前 or 直後付近に仕込まれていることが多いです。
分かりやすいのが「the_title」というフィルターフックです。このフィルターフックはデータベースから取得したデータの一部であるタイトルを加工するためのものになります。
例えば the_title フィルターフックにタイトルの前後に “★” を挿入するような関数をフックしとけば、ページ表示時にタイトルの前後に “★” が付加されるようになります
フックとは? → ★フックとは?★
他にも様々なフィルターフックがワードプレスには用意されています。イメージしやすいものをいくつかピックアップしてみました。
the_content
データベースから読み込んだページ(投稿など)の記事本文を加工するためのフィルターフックです。
このフィルターフックにフックされた関数は、「ワードプレスインストールフォルダ/wp-includes/post-template.php」の下記で実行されます。
function the_content( $more_link_text = null, $strip_teaser = false ) {
$content = get_the_content( $more_link_text, $strip_teaser );
/**
* Filters the post content.
*
* @since 0.71
*
* @param string $content Content of the current post.
*/
$content = apply_filters( 'the_content', $content );
$content = str_replace( ']]>', ']]>', $content );
echo $content;
}
後述で解説しますが apply_filters 関数がフィルターフックにフックされた関数を実行する関数になります。
同様にデータベースから読み込んだデータを加工するためのフィルターフックには下記のようなものもあります。
- the_title:表示するタイトル加工用
- comment_text:表示するコメント本文加工用
- get_category:表示するカテゴリ加工用
title_save_pre
データベースに書き込むページのタイトルを加工するためのフィルターフックです。
このフィルターフックにフックされた関数は、「ワードプレスインストールフォルダ/wp-includes/post.php」の下記で実行されます。
function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
$int_fields = array( 'ID', 'post_parent', 'menu_order' );
/* 〜略〜 */
if ( 'edit' == $context ) {
/* 〜略〜 */
} elseif ( 'db' == $context ) {
/* 〜略〜 */
if ( $prefixed ) {
/* 〜略〜 */
$value = apply_filters( "{$field_no_prefix}_save_pre", $value );
/* 〜略〜 */
同様にデータベースに書き込む前のデータを加工するためのフィルターフックには下記のようなものもあります。
- content_save_pre:データベースに保存する記事本文加工用
- comment_save_pre:データベースに保存するコメント本文加工用
- category_save_pre:データベースに保存するカテゴリ加工用
その他のフィルターフック
その他にも、非常にたくさんのフィルターフックが様々な用途・タイミング用にワードプレスに仕込まれています。このフィルターフックの一覧は下記ページで公開されています。
参考 フィルタフック一覧WordPressCodex日本語版フィルターフックの戻り値
アクションフックと違い、フィルターフックにフックされた関数は戻り値を返却することが可能です。加工したデータ(タイトル・記事本文・コメントなどなど)を返却できないと意味がないので、当然と言えば当然ですね。
アクションフックとフィルターフックの違い
アクションフックとフィルターフックの違いをまとめておくと下記のようになります。
フックの役割の違い
アクションフックとフィルターフックとでは、役割が下記のように違います
- アクションフック:ワードプレスの動きそのものを制御
- フィルターフック:データの加工
フックする関数の戻り値の違い
またフックにフックする関数の戻り値には下記のように違いがあります。
- アクションフック:なし
- フィルターフック:加工済みのデータ
スポンサーリンク
フックの使い方
続いてはフックをプログラムにどのようにして記述して利用するかを具体的に説明していきます。
フックとは?で解説したようにフックに対して行う処理は主に下記の2つです。
- フックに関数をフックする
(フックした関数を取り除く事も可能) - フックにフックされた関数を実行する
ここまで説明ではあまり触れてきませんでしたが、フックからフックを取り除くことも可能です。そしてフックの種類で説明したようにフックには下記の2種類が存在します。
- アクションフック
- フィルターフック
アクションフックとフィルターフックそれぞれに対してフックを使用するために用いる関数が異なります。
ここでは、それぞれの処理に対して、アクションフックとフィルターフックそれぞれに対して用いる関数の解説を行います。
フックに関数をフックする
まずは「フックに関数をフックする」関数について解説します。
add_action
add_action 関数は「アクションフックに関数をフックする」関数です。
使い方は下記の通りです。
<?php add_action( $hook, $function, $priority, $arg_num ); ?>
各引数の詳細は下記の通りです。
- $hook:アクションフック名(必須)
- $function:$hook で指定するアクションフックにフックする関数の関数名(必須)
- $priority:関数実行順序の優先度。$hook で指定するアクションフックに複数の関数がフックされる場合、値が小さい関数から早く実行される(オプション、省略時は「10」が設定される)
- $arg_num:$function で指定する関数の引数の数(オプション、省略時は「1」が設定される)
remove_action
remove_action 関数は「アクションフックにフックされた関数を取り除く」関数です。
使い方は下記の通りです。
<?php remove_action( $hook, $function, $priority ); ?>
各引数の詳細は下記の通りです。
- $hook:アクションフック名(必須)
- $function:$hook で指定するアクションフックにフックする関数の関数名(必須)
- $priority:関数実行順序の優先度
add_filter
add_filter 関数は「フィルターフックに関数をフックする」関数です。
使い方は下記の通りです。
<?php add_filter( $hook, $function, $priority, $arg_num ); ?>
各引数の詳細は下記の通りです。
- $hook:フィルターフック名(必須)
- $function:$hook で指定するフィルターフックにフックする関数の関数名(必須)
- $priority:関数実行順序の優先度。$hook で指定するフィルターフックに複数の関数がフックされる場合、値が小さい関数から早く実行される(オプション、省略時は「10」が設定される)
- $arg_num:$function で指定する関数の引数の数(オプション、省略時は「1」が設定される)
remove_filter
remove_filter 関数は「フィルターフックにフックされた関数を取り除く」関数です。
使い方は下記の通りです。
<?php remove_filter( $hook, $function, $priority ); ?>
各引数の詳細は下記の通りです。
- $hook:フィルターフック名(必須)
- $function:$hook で指定するフィルターフックにフックする関数の関数名(必須)
- $priority:関数実行順序の優先度
フックにフックされた関数を実行する
続いては「フックにフックされた関数を実行する」関数について解説します。
do_action
do_action 関数は「アクションフックにフックされた関数を実行する」関数です。
使い方は下記の通りです。
<?php do_action( $hook, $arg, $arg, ... ); ?>
各引数の詳細は下記の通りです。
- $hook:アクションフック名(必須)
- $arg:アクションフックにフックされた関数に渡す引数(オプション。複数指定可能)
do_action_ref_array
do_action_ref_array 関数は、do_action 関数同様に「アクションフックにフックされた関数を実行する」関数です。do_action 関数との違いは「引数が配列」である点です。
使い方は下記の通りです。
<?php do_action( $hook, $arg_array ); ?>
各引数の詳細は下記の通りです。
- $hook:アクションフック名(必須)
- $arg_array:アクションフックにフックされた関数に渡す配列型引数(必須)
apply_filters
apply_filters 関数は「フィルターフックにフックされた関数を実行する」関数です。
使い方は下記の通りです。
<?php apply_filters( $hook, $value, $arg, ... ); ?>
各引数の詳細は下記の通りです。
- $hook:フィルターフック名(必須)
- $value:フックされた関数内で加工するデータ(必須)。このデータを加工したものが戻り値となる
- $arg:$value 以外の引数(オプション)
apply_filters_ref_array
apply_filters_ref_array 関数は、apply_filters 関数同様に「フィルターフックにフックされた関数を実行する」関数です。apply_filters 関数との違いは「引数が配列」である点です。
使い方は下記の通りです。
<?php apply_filters_ref_array( $hook, $arg_array ); ?>
各引数の詳細は下記の通りです。
- $hook:フィルターフック名(必須)
- $arg_array:アクションフックにフックされた関数に渡す配列型引数(必須)
スポンサーリンク
ワードプレスのフックの調べ方
それぞれのフックに対してフックした関数がどのタイミングで実行されるかは、ワードプレス以下の PHP に対してアクションフック名で検索すれば参照することが可能です。
例えば私は eclipse を使ってアクションフック名を検索しながらこのページを書いてます。eclipse で「widgets_init」を検索した結果は下記のような感じになります。
do_action( ‘フック名’); が実行されている箇所を調べれば、どこでそのフックにフックされた関数が実行されているかが分かります。
また apply_filters( ‘フック名’, ‘関数名’); の「関数名」の定義を調べれば、そのフックにフックする関数の作り方も調べることができます。
また下記ページに解説している方法で、フックする関数の中にブレークポイントを設定してそこでプログラムを止めてやれば、後はそこからプログラムを進めて呼び出し元を辿っていくことで、どこからフックした関数が実行されたのかを調べることも可能です。
Eclipse にデバッガー(Xdebug)を導入テーマ・プラグインを開発するときや、ワードプレスの動きを調べるのに便利なので、デバッガーの導入は超オススメです!
まとめ
このページではワードプレスの「フック」について解説しました。
フックを利用することで、ワードプレスのテーマ開発やプラグイン開発の自由度が一気に高まります。是非フックを使いこなし、自分好みのテーマやプラグインを開発していきましょう!
解説シリーズとしては私のサイトで「クエリ」についても解説しています。こちらもワードプレスでの開発では非常に重要!興味のある方は是非読んでみてください!
ワードプレスのクエリとは?メインクエリとサブクエリの違いは?