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でカテゴリー名も検索にひっかけるプラグイン「Search Everything」
WordPressでカテゴリーも検索にひっかけるプラグイン「Search Everything 8.
-
-
WordPress 自作フォーム その1(サンプルと設置)
Wordpress でプラグインを使わずにフォームをやってみます。 簡単に名前、メールアドレス、メ
-
-
WordPress フォルダー・ファイル系の関数 is_dir や opendir や exif_imagetype で Warning エラー
Wordpress の管理画面でフォルダーの中身を読み込む関数 opendir でエラー Word
-
-
WordPress の PHP をちょっと見てみよう Ⅱ
前記事の続きで、wp-settings.php の68行目あたりから見ていきます。 <今回のピ
-
-
WordPress エラー:Failed to load plugin: table from url https://cdn.tinymce.com/4/plugins/table/plugin.min.js
WordPress エラーの状態 WordPress 管理画面のテキスト入力欄で(ビジュアルタブの
-
-
WordPress レスポンシブ テンプレート の メニューやブログの設置
前回の 「WordPress レスポンシブ テンプレートコーポレート用(シンプル・カスタマイズ用)ダ
-
-
WordPress カレンダー カスタマイズ(add_filter版)
前回、「WordPress の PHP をちょっと見てみよう Ⅲ」でフックをやったので、カレンダーで
-
-
「All-in-One WP Migration」プラグインで 簡単に WordPress のサーバー移行する手順メモ
1.移行元サイトでのデータエクスポート 「All-in-One WP Migration(公式リン
-
-
WordPress twentyseventeen の function.php を見る – その1
WordPress の最低限の機能だけのシンプルなテンプレートが欲しかったので、作っておくことにしま
-
-
ロリポップでWordPressのPHPバージョン7.1に変更後「サイトに技術的な問題が発生しています。」
WordPress.org の推奨環境 PHP7以上 MySQL5.6以上またはMaria