WordPressのアクションやフィルタの適用を最小限にする
「add_action」や「add_filter」によってフックすることでWordPressの機能を拡張することができますが、闇雲に追加すると他で追加されたものと競合して予期せぬ動作になってしまうことがあります。
remove_action,remove_filter の利用
以下のような記述をすると適用範囲を最小限にとどめ、他への影響も少なくなります。
(PHP5.3以上)
$func = function ( $wp_query ) use ( &$func ) {
/** @var \WP_Query $wp_query */
$wp_query->set( 'posts_per_page', 6 );
remove_action( 'pre_get_posts', $func );
};
add_action( 'pre_get_posts', $func );
必ずしも無名関数を使用する必要はなく、普通に関数を定義して「add_action」や「remove_action」を呼べば同じように適用を最小限にすることもできます。
function test_function( $wp_query ) {
/** @var \WP_Query $wp_query */
$wp_query->set( 'posts_per_page', 6 );
remove_action( 'pre_get_posts', 'test_function' );
}
add_action( 'pre_get_posts', 'test_function' );
その場合はPHP5.3未満にも対応可能ですが、ちょっとした適用をしたい場合も将来にわたって他と被らない関数名をいちいち考える必要があります。
使いどころ
例に挙げたpre_get_postsはメインで表示するための投稿の取得やナビゲーションメニューの取得など、たいてい一回のページの表示で複数回呼ばれます。
特定のフィルタやアクションの後の一回だけで適用されればよい場合は、そのフィルタやアクション内で上のような記述にしておけば別の個所で適用される心配はなくなります。
さらに不要なフィルタやアクションを消すことで不要なプログラムが実行されなくなり、多少の高速化も望めます。
ただし上記のような対応が全く不要なアクションやフィルタもあります。
「init」や「template_redirect」のような一度だけしか呼ばれることがないものがそれにあたります。
一度しか呼ばれないため remove してもしなくても動作としては何も変わりません。
むしろ remove する処理が無駄な負担になるため行わないほうがよいです。
まとめ
プラグインやテーマを作成する場合はこのようなことを考慮して適切にremoveも行い、ほかのプラグインなどに影響を与えないようにする必要があります。
逆にこのようなことが考慮されていないプラグインやテーマは作者がWordPressについてあまり詳しくなく、セキュリティやパフォーマンス的にまずい可能性があるため使用を避けたほうが無難です。
かなり多くの人に利用されている大手の無料テーマやクラウドソーシングサービスでプロを名乗っている人が作っているプラグインでも致命的なセキュリティの問題を含んでいることがあります。
不安な場合は一度ソースコードを眺めて上記のようなことや nonceの使用によるCSRF対策、サニタイズやエスケープ処理によるXSS対策などが考慮されているか確認したほうがよいでしょう。