WordPress の PHP をちょっと見てみよう Ⅲ
前記事の続きで、wp-settings.php の91行目あたりから見ていきます。
次は、wp-includes/default-filters.php を読み込んでいるので、開きます。
foreach ( array( 'pre_term_name', 'pre_comment_author_name', 'pre_link_name', 'pre_link_target', 'pre_link_rel', 'pre_user_display_name', 'pre_user_first_name', 'pre_user_last_name', 'pre_user_nickname' ) as $filter ) { add_filter( $filter, 'sanitize_text_field' ); add_filter( $filter, 'wp_filter_kses' ); add_filter( $filter, '_wp_specialchars', 30 ); } ・・・・
やっとやりたい関数が出てきた!
最後にこのadd_filter() と add_action() というフック時に使う関数を見て、終わりにしようと思います。
<今回のピックアップ項目>
- フックとは?
- add_filter() の簡単な例
- the_title()で表示したくない場合
- add_filter() と add_action() の違い(=ない)
- 全てのフック関数を表示するコード
- apply_filters() と do_action() の違いは引数に配列が渡せるかどうか
フックとは?
フックについては、WordPress 日本語Codex「プラグイン API」 で説明していますが、ちょっと難解でした。
フックには、add_filter()で設定する(フィルター) と add_action() で設定する(アクション)の2種類があります。
この関数がある大きな理由は、デフォルトで設定してある関数群(=API)に手を加えることなく、関数を追加・変更出来るということだと思います。
フックを日本語で言うなら、ある関数に後から関数を追加削除(変更)出来るという認識でいいのかなと思います。
追加(フック)する関数名を設定する。
add_filter(‘追加される元関数’, ‘追加する関数’, ‘優先度’, ‘引数の数’ );
add_action(‘追加される元関数’, ‘追加する関数’, ‘優先度’, ‘引数の数’ );
(フックから)削除する関数名を設定する。
remove_filter(‘削除される元関数’, ‘削除する関数’, ‘優先度’, ‘引数の数’ );
remove_action(‘削除される元関数’, ‘削除する関数’, ‘優先度’, ‘引数の数’ );
追加(フック)された関数を全部実行。
apply_filters(‘追加された元関数'[,引数・・][,引数・・]);
do_action(‘追加された元関数'[,引数・・][,引数・・]);
やはり分かりずらいので、簡単な例でやってみようと思います。
add_filter() の簡単な例
例えば、the_profile() というのが、元々テーマ外でWP側で設定されているとします。
カスタマイズする時などに、テーマ内 functions.php の中でデフォルトのWP関数に追加(フック)する関数を設定します。
//テーマ外に設定してあるデフォルトのWP関数だとします。 function the_profile($n1, $n2){ echo ' 私:'.$n1; echo ' 猫:'.$n2; } //テーマ内 functions.php の中で関数をフックする。 add_filter('the_profile', 'my_profile', 10, 2); function my_profile($n1, $n2){ echo '私の名前は、'.$n1 .'です。猫の名前は、' .$n2 . 'です。'; } //テーマ内で使う $myname = '山田'; $catname = 'たま'; apply_filters('the_profile', $myname , $catname );//フックされてる関数の方を実行する the_profile($myname , $catname);//デフォルトの関数もそのまま残っている
表示結果「私の名前は、山田です。猫の名前は、たまです。」「 私:山田 猫:たま」
デフォルトの関数をいじらずに関数を変更出来ました。
add_filter()が複数の例
//テーマ外に設定してあるデフォルトのWP関数だとします。 function the_profile($n1){ echo '私は、'.$n1; } //テーマ内 functions.php の中で関数をフックする。 add_filter('the_profile', 'my_profile'); add_filter('the_profile', 'trim');//前後の空白などを削除するPHP関数 function my_profile($n1){ return ' 私の名前は、'.$n1 .'です。 '; } //テーマ内で使う $myname = '山田'; echo apply_filters('the_profile', $myname);//フックされてる関数の方を実行表示する the_profile($myname);//デフォルトの関数もそのまま残っている
表示結果「私の名前は、山田です。」「私は、山田」
my_profile()も、trim()で前後の半角スペースも削除された、両方の関数が実行された結果になります。(半角スペースは表示だと見れません、もし確認したい場合はソースの方を確認してください。)
複数だと、優先順位で指定した順番に、すべてがフックされた結果になります。
再帰呼び出しのような例(=自分自身の中でapply_filters()を実行している例)
実際は以下のようにフック関数の中で、実行関数(apply_filters()やdo_action())を呼び出してる構造が多いのでやってみます。
//テーマ外に設定してあるデフォルトのWP関数だとします。 function the_profile($n1,$n2,$n3){ apply_filters('the_profile', $n1,$n2,$n3); } add_filter('the_profile', 'my_profile',10,3); add_filter('the_profile', 'cat_profile',10,3); add_filter('the_profile', 'dog_profile',10,3); function my_profile($n1,$n2,$n3){ echo '私の名前は、'.$n1 .'です。'; } function cat_profile($n1,$n2,$n3){ echo '猫の名前は、'.$n2 .'です。'; } function dog_profile($n1,$n2,$n3){ echo '犬の名前は、'.$n3 .'です。'; } //テーマ内で使う $myname = '山田'; $catname = 'たま'; $dogname = 'ポチ'; the_profile( $myname,$catname,$dogname);
表示結果「私の名前は、山田です。猫の名前は、たまです。犬の名前は、ポチです。」
簡単な例をやったら、自分的にはなんとなく分かってきました。
the_title() のフィルターを見てみる
wp-includes/default-filters.php に戻って、分かりやすくタイトルのところを見ていきます。
add_filter( 'the_title', 'wptexturize' ); add_filter( 'the_title', 'convert_chars' ); add_filter( 'the_title', 'trim' );
wp-includes/formatting.php の中で第2引数のフックする関数が設定されています。
function wptexturize($text) { ....(エスケープ処理).... } function convert_chars($content, $deprecated = '') { ....(エスケープ処理).... }
wp-includes/post-template.php の中 でデフォルトの関数を設定しています。
function the_title($before = '', $after = '', $echo = true) { $title = get_the_title(); ・・・・(省略)・・・・ if ( $echo ) echo $title; else return $title; } ・・・・(省略)・・・・ function get_the_title( $post = 0 ) { $post = get_post( $post ); $title = isset( $post->post_title ) ? $post->post_title : ''; $id = isset( $post->ID ) ? $post->ID : 0; ・・・・(省略)・・・・ //wptexturize()convert_chars()trim()が全て実行された値を返している return apply_filters( 'the_title', $title, $id ); } ・・・・(省略)・・・・
the_title() を使用した時点で、get_the_title()を改して、既に3つのフィルターフックがかかった(エスケープ処理をした)値になります。
このWP側でデフォルトでフィルターとアクションを設定してるファイルが、wp-includes/default-filters.php ということになります。(ただ、設定してるのは、このファイルだけで全てではないです。)
remove_filter() というフィルターを削除する関数も用意されていますので、後から削除したり出来るようになっています。
the_title()で表示したくない場合
余談ですが、the_title() 関数のコードを見たら、$before,$after,$echo 引数ってあったんだって今知りました。
今までタイトルをいじりたい時に、the_title()を使うと表示されてしまうので、get_the_title()でやっていました。
引数設定が3つもあり、$echo 引数を false にすれば出来たんですね。
$title = the_title();//表示してしまう。 $title = the_title('<h1>','</h1>',false);//表示しないで変数に格納出来る。しかも前後のタグなども指定出来るようになっていた。
これだけでもコード見てみて、よかったなって思いました。
add_filter() と add_action() の違い(=ない)
add_filter() はさっき抜かした wp-includes/plugin.php で定義されています。
wp-includes/plugin.php を開きます。
global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; ・・・・(省略)・・・・ function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { ・・・・(省略)・・・・ } ・・・・(省略)・・・・ function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) { return add_filter($tag, $function_to_add, $priority, $accepted_args); }
(ソースを読む気力も知識も追いつかなくなったので、)詳しくは読めませんが、だいたい書くと、はじめに $wp_filter などのグローバルな変数を用意しています。
add_filter()では、そのグローバル配列にfunction名を入れておいて、apply_filters()、do_action()では、call_user_func_array()関数を使って、配列で持っているfunction名を実行しています。(ひどい説明)
そして、ソースを見て驚きなのが、add_action() は、add_filter() をそのまま実行しているだけでした。
apply_filters() と do_action() はちょっと違いますが、add_filter() と add_action() は、まったく同じだということが分かりました。
全てのフック関数を表示するコード
フックしたい関数が、フィルターなのか、アクションなのか、どっちかを知るには、以下のマニュアルの一覧で確認したり、その関数が、apply_filters() と do_action()どっちで実行しているかを確認すれば分かります。
プラグイン API/フィルターフック一覧
プラグイン API/アクションフック一覧
ただ、その都度調べるのがちょっと大変です。
add_filter() と add_action() が同じだということは、どんな関数がフックされているか見るには、$GLOBALS[‘wp_filter’] の中に全部配列で入っているはずなので、以下を書けば、両方見れるんじゃないかと思いました。
print_r($GLOBALS['wp_filter']['ここに見たい関数名']);
これだと、配列で見ずらいので、以下のように回してみました。
foreach ($GLOBALS['wp_filter']['ここに見たい関数名'] as $key => $value){ echo '【優先順位:'.$key.'】フックしてる関数:'; foreach ($value as $key2 => $value2){ echo ' ['.$key2.']'; } echo '<br>'; }
例えば、テンプレートのindex.php 内で、the_title() 関数やってみると、結果は以下のようになりました。
the_title() で設定した表示結果
【優先順位:10】フックしてる関数: [wptexturize] [convert_chars] [trim]
【優先順位:11】フックしてる関数: [capital_P_dangit]
あってるんじゃないかと(多分)。
これでソースをカスタマイズしながら、その場でフックしてる関数が簡単に見れていいかもしれないです。(※見れるのはフックしてる関数だけです、全部ではありません。)
apply_filters() と do_action() の違いは引数に配列が渡せるかどうか
この2つの違いでまず気になるのが、引数です。
function apply_filters( $tag, $value ) {....
function do_action($tag, $arg = '') {....
do_action()は、配列を扱えるということでしょうか。
簡単な例でやってみると、引数が配列の場合は、do_action() じゃないと出来ません。
アクションじゃないとダメな例
function the_profile($p_array){ do_action('the_profile', $p_array);//ここがapply_filters() で、 } add_action('the_profile', 'my_profile');//ここがadd_filtesr()で、 add_action('the_profile', 'cat_profile');//ここがadd_filtesr()で、 add_action('the_profile', 'dog_profile');//ここがadd_filtesr()だと、配列の1つしか値を渡せない。 function my_profile($p_array){ echo '私の名前は、'.$p_array['myname'] .'です。';//フィルターだと、引数がここしか表示出来ない。 } function cat_profile($p_array){ echo '猫の名前は、'.$p_array['catname'] .'です。'; } function dog_profile($p_array){ echo '犬の名前は、'.$p_array['dogname'] .'です。'; } //テーマ内で使う $profile['myname'] = '山田'; $profile['catname'] = 'たま'; $profile['dogname'] = 'ポチ'; the_profile($profile);
表示結果「私の名前は、山田です。猫の名前は、たまです。犬の名前は、ポチです。」
この2つの違いをまず言うなら、引数が配列が扱えるかどうか、ということでいいんじゃないかと思いました。
最後に
というわけで、自分的にやりたい関数を見たところで、「WordPress PHP を見てみよう」のシリーズは終わりにしようと思います。
結局 wp-settings.php の途中で終わってしまいました。
(特にこの回の説明には、独自の解釈などが多く入っているので、間違えなどあるかもしれません。)
関連記事
-
WordPress リビジョンを削除し、テーブルを最適化してDBの容量を削減
WordPress リビジョン機能 リビジョンは過去の記事を保存してくれる WordPress の
-
WordPress レスポンシブ テンプレートコーポレート用(シンプル・カスタマイズ用)ダウンロード
WordPress レスポンシブ テンプレートコーポレート用(シンプル・カスタマイズ用)ダウンロード
-
WordPress twentyseventeen の function.php を見る – その1
WordPress の最低限の機能だけのシンプルなテンプレートが欲しかったので、作っておくことにしま
-
WordPress レスポンシブ テンプレート 元にサイトを作ってみる その2
DEMO を見る カスタム投稿タイプ functions.php 今回は3つのリストメニュ
-
WordPress タイトルの変更
テンプレートタグ the_title(); get_the_title(); WordPress
-
WordPress フォルダー・ファイル系の関数 is_dir や opendir や exif_imagetype で Warning エラー
Wordpress の管理画面でフォルダーの中身を読み込む関数 opendir でエラー Word
-
WordPress の PHP をちょっと見てみよう Ⅰ
WordPress には、たくさんのファイルが入っています。 ここではテーマ内ではなく、トップ
-
wordpress カスタム投稿で 2ページ目以降が404になってしまう
wordpress のカスタム投稿で、ニュースのページを作っていました。 ニュース一覧で、ペー
-
WordPress で VR させて、360°のパノラマ画像を表示する
WordPress.com内ショートコードで VR させる WordPress.com内で、VR(
-
レンタルサーバでWordPressを設置してみよう!
WordPress.com 内に、ブラウザだけで無料でサイトを作成出来きるサービスもありますが、Wo