PHP

【WordPress】フィルターやアクションに登録されている関数をリストアップする方法

更新日:2022/12/20

WordPressのフィルター機能は、特定の機能のカスタマイズ性を高めるのに効果的です。
その反面呼び出される関数の把握を難しくするため、不具合時等の状況把握が困難になるデメリットがあります。

そこで、フィルター機能で呼び出されるフック関数をリストアップする方法をお伝えします。

 

フィルターフックをリストアップする関数

フィルターの情報は、グローバル変数 $wp_filter で管理されています。
$wp_filterWP_Hookクラスの配列なので、このクラスのコードを解析して内容を取得する関数を作成しました。

WP_Hookクラスのソース:wp-includes\class-wp-hook.php
// フック関数をリストアップする
function list_filter( $hook_name )  {
	global $wp_filter;
	echo "*************".$hook_name."</br>";
	if ( ! isset( $wp_filter[ $hook_name ] ) ) {
		echo "No data";return;
	}

	$priorities =  $wp_filter[ $hook_name ]->callbacks;

	foreach ( $priorities as $priority => $callbacks ) {
		foreach ( $callbacks as $value ) {
			echo $priority . ' , ' . get_function_info( $value['function'] ) . '</br>';
		}
	}
}
// コールバック変数から関数名・クラス名を取得する
function get_function_info( $functionData ){
	try{
		$is_class = is_array( $functionData );
		$rf = $is_class
			? new ReflectionClass($functionData[0])
			: new ReflectionFunction($functionData);

		$function_name = $is_class
			? $rf->getName() . '-&gt;'. $functionData[1]
			: ($rf->getClosureScopeClass() === null ?  ''
				: $rf->getClosureScopeClass()->getName() . '-&gt;') . $rf->getName();

		$start_line = $is_class
			? $rf->getMethod($functionData[1])->getStartLine()
			: $rf->getStartLine() ;

		$fnames = array_reverse( preg_split( "/[\\/\\\\]/" , $rf->getFileName()));
		$fname = '/' . $fnames[1] . "/" . $fnames[0];
		return $function_name  . ' [' . $fname .'(' . $start_line . ')]';
	}catch (Exception $e){
		return '例外エラー: '.  $e->getMessage();
	}
}

グローバル変数の$wp_filterのキーは、フィルターおよびアクション名です。
そこで $wp_filter[フィルター名]で、フィルターに関する情報を取得できます。

get_function_info()関数は、コールバック変数から関数名やクラス名、ファイル名等を取得しています。

使用例としてthe_contentフィルターのフック関数をリストアップしてみます。
表示したい位置で、次のコードを実行します。

list_filter('the_content');

すると、次のような結果が出力されます。

*************the_content
8 , WP_Embed->run_shortcode [/wp-includes/class-wp-embed.php(62)]
8 , WP_Embed->autoembed [/wp-includes/class-wp-embed.php(440)]
9 , do_blocks [/wp-includes/blocks.php(1084)]
10 , wptexturize [/wp-includes/formatting.php(37)]
10 , wpautop [/wp-includes/formatting.php(442)]
10 , shortcode_unautop [/wp-includes/formatting.php(820)]
10 , prepend_attachment [/wp-includes/post-template.php(1691)]
10 , wp_filter_content_tags [/wp-includes/media.php(1776)]
10 , wp_replace_insecure_home_url [/wp-includes/https-migration.php(51)]
11 , capital_P_dangit [/wp-includes/formatting.php(5539)]
11 , do_shortcode [/wp-includes/shortcodes.php(205)]
20 , convert_smilies [/wp-includes/formatting.php(3419)]

ファイル名と行番号も表示されるので、問題把握がスムーズに行えると思います。

 

ショートコード化

上のコードは同じテンプレートの全てのページに表示されるので、運営中のサイトは使いにくいです。
そこで、ショートコードから呼び出せるようにしてみます。

function list_filter_shortcode($atts){
	extract(shortcode_atts(array(
		'hook_name'=>"",
	),$atts));
	global $list_filter_targets;
    if( !isset($list_filter_targets) ) $list_filter_targets=[];

	$list_filter_targets[] = $hook_name;
	if( count($list_filter_targets ) === 1 ) {
		add_action('wp_footer','list_filter_loop',9999999);
	}
}
function list_filter_loop(){
	global $list_filter_targets;
	foreach ( $list_filter_targets as $target){
		list_filter( $target );
	}
}

ショートコードではフィルター名を配列にセットして、wp_footerアクションを登録しています。
フィルター一覧は、wp_footerアクションで出力します。

wp_footerアクションで出力しているのは、ショートコード呼び出し後にフィルターが追加されるケースを考慮しているからです。

問題点はwp_footerより前にフィルターが削除されるとリストアップできない点です。
この場合は、リストアップするタイミングを変更してみてください。

例として、新規記事を作成して、次のショートコードを記述してみてください。

[list_filter hook_name="the_content"]

すると、the_contentフィルターの内容がフッターに出力されます。

WordPressはHTMやCSSの知識も必要。総合的な知識を身につけよう。

更新日:2022/12/20

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。