WordPress コアや他の WordPress プラグインとうまく協調して動作するように、コードを構成するのに役立つベスト・プラクティスをいくつか紹介します。
ネーミング衝突の回避
ネーミング衝突は、あなたのプラグインが他のプラグインと同じ変数名、関数名、クラス名を使用している場合に起こります。
幸いなことに、以下の方法でネーミングの衝突を避けることができます。
手続き的コーディング手法
デフォルトでは、すべての変数、関数、クラスは グローバル名前空間 で定義されます。つまり、あなたのプラグインは、他のプラグインによって設定された変数、関数、クラスをオーバーライドできます (逆もまた然り)。関数やクラスの 内部 で定義された変数は、この影響を受けません。
すべてに接頭辞をつける
グローバルにアクセス可能なすべてのコードには、ユニークな 識別子を接頭辞として付ける必要があります。接頭辞は他のプラグインとの競合を防ぎ、プラグインがあなたの変数を上書きしたり、誤ってあなたの関数やクラスを呼び出したりするのを防ぎます。
他のプラグインとの競合を避けるため、接頭辞は、少なくとも4文字、5文字以上を推奨します。一般的な英単語を使うのは避け、プラグイン独自のものを選ぶべきです。私たちは WordPress.org だけで何万ものプラグインをホストしています。私たちのサーバーの外側には、さらに何十万ものプラグインがあります。競合に 遭遇する ことになるでしょう。
これを可能にする良い方法は、接頭辞を使うことです。たとえば、あなたのプラグインが「Easy Custom Post Types」という名前なら、以下のような名前を使うことができます:
function ecpt_save_post()
define( 'ECPT_LICENSE', true );
class ECPT_Admin{}
namespace EasyCustomPostTypes;
update_option( 'ecpt_settings', $settings );
__
(アンダースコア2つ)、wp_
、WordPress
、_
(アンダースコア1つ)
「サブ」プラグイン (WooCommece 機能拡張など) のコードを作成する場合、同様に通常の接頭辞 (Woo、WooCommerce など) を使用しないようにする必要があります。
クラスや名前空間の 内部 であれば使用できますが、独立した関数、名前空間、クラスとしては使用できません。
翻訳のために _n()
や __()
を使うのであれば問題ありません。ここでは WordPress のコア機能ではなく、あなたがプラグイン用に作成する関数についてのみ述べています。実際、これらのコア機能こそが、上に紹介した接頭辞をプラグイン内で使わない 理由 です ! 誰しもユーザーの WordPress を壊したくはないでしょう。
忘れないでください: 良い接頭辞名とは、あなたのプラグインに固有のものです。これは、あなたや後から参加する人のデバッグに役立ちますし、競合を防ぐことにもなります。
接頭辞をつけなければ ならない コードには、以下のようなものがあります:
- (名前空間がない場合) 関数
- (名前空間がない場合) クラス、インターフェイス、および Trait
- 名前空間
- グローバル変数
- オプションおよび Transient
既存の実装に対するチェック
PHP には、変数や関数、クラス、定数の実在性を検証するための関数が多数用意されています。これらはすべて、実体が存在すれば true を返します。
- 変数: isset() (配列、オブジェクトなどを含む)
- 関数: function_exists()
- クラス: class_exists()
- 定数: defined()
すべての関数やクラスで (!function_exists('NAME')) {
を使うことはすばらしいアイデアに思えるかもしれませんが、致命的な欠点がある点に注意してください。もし他の何かが同じ名前の関数を持ち、そのコードが先に読み込まれると、あなたのプラグインは壊れてしまいます。if-exists を使って関数やクラスを置き換えたりオーバーライドしたりするのは、共有 ライブラリだけにとどめてください。
例
// Create a function called "wporg_init" if it doesn't already exist
if ( ! function_exists( 'wporg_init' ) ) {
function wporg_init() {
register_setting( 'wporg_settings', 'wporg_option_foo' );
}
}
// Create a function called "wporg_get_foo" if it doesn't already exist
if ( ! function_exists( 'wporg_get_foo' ) ) {
function wporg_get_foo() {
return get_option( 'wporg_option_foo' );
}
}
オブジェクト指向プログラミング手法
名前の衝突問題にもっと簡単に取り組む方法は、プラグインのコードに class を使うことです。
希望するクラス名がすでに使われているかどうかをチェックする必要はありますが、あとは PHP がやってくれます。
例
if ( ! class_exists( 'WPOrg_Plugin' ) ) {
class WPOrg_Plugin {
public static function init() {
register_setting( 'wporg_settings', 'wporg_option_foo' );
}
public static function get_foo() {
return get_option( 'wporg_option_foo' );
}
}
WPOrg_Plugin::init();
WPOrg_Plugin::get_foo();
}
ファイル構成
プラグインディレクトリのルートレベルには、ファイル plugin-name.php
と、必要に応じてファイル uninstall.php を置いてください。その他のファイルは、可能な限り、サブフォルダーに整理しましょう。
フォルダー構造
明確なフォルダー構造は、あなたやあなたのプラグインで作業している他の人が同じようなファイルをまとめておくのに役立ちます。
参考までに、フォルダー構造の例を挙げておきます:
/plugin-name
plugin-name.php
uninstall.php
/languages
/includes
/admin
/js
/css
/images
/public
/js
/css
/images
プラグイン・アーキテクチャー
プラグインに選択するアーキテクチャー (またはコード構成) は、プラグインのサイズによって異なります。
WordPress のコアやテーマ、他のプラグインとの相互作用が限られている、小規模で単一目的のプラグインの場合、複雑なクラスを設計するメリットはほとんどありません。ただし、そのプラグインが後で大きく拡張されることがわかっている場合は、別です。
コードがたくさんある大規模なプラグインでは、まずクラスを考慮に入れてスタートしましょう。スタイルファイルとスクリプトファイル、そしてビルド関連ファイルも分けてください。こうすることで、コードを構成しやすくなり、プラグインの長期的なメンテナンスがしやすくなります。
条件付き読み込み
管理者用のコードと一般向けのコードを分けておくと便利です。条件式 is_admin() を使いましょう。これは、ユーザーが認証済みであること、または管理者レベルのアクセス権を持っていることを示すものではないため、依然として権限チェックを実施する必要があります。ユーザー権限のチェックを参照してください。
例:
if ( is_admin() ) {
// we are in admin mode
require_once __DIR__ . '/admin/plugin-name-admin.php';
}
ファイルへの直接アクセスの回避
セキュリティの観点から、グローバル ABSPATH
が定義されていない場合は、アクセスを許可しないようにするのがグッド・プラクティスです。これはメインプラグインファイルのような、クラスや関数の定義以外のコードを含むファイルにのみ適用されます。
このコードをファイルの先頭に記述することで、実装できます:
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
アーキテクチャー・パターン
アーキテクチャー・パターンはいくつも考えられますが、大まかに3つのバリエーションに分類できます:
アーキテクチャー・パターンの説明
上記のうち、より複雑なコード構成の具体的な実装は、すでにチュートリアルやスライドとして書かれています:
起点となるボイラープレート (ひな型)
新しいプラグインを書くたびにゼロから始めるのではなく、ボイラープレート から始めるとよいでしょう。ボイラープレートを使う利点のひとつは、自分のプラグインに一貫性を持たせることです。もしあなたがボイラープレートを使っていれば、ボイラープレートを使うことで、他の人はすでに慣れ親しんでいるので、彼らがあなたのコードに貢献しやすくなります。
これらはまた、異なるが同等のアーキテクチャーのさらなる例となります。
- WordPress プラグイン・ボイラープレート: WordPress プラグイン開発のための基盤で、プラグインを構築するための明確で一貫したガイドを提供することを目的としています。
- WordPress プラグイン・ブートストラップ: Grunt、Compass、Git、Svn を使って WordPress プラグインを開発するための基本的なブートストラップです。
- WP Skeleton Plugin: ユニットテストと開発用の Composer の使用に焦点を当てた、ひな型プラグインです。
- WP CLI Scaffold: WP CLI の Scaffold コマンドは、CI 設定ファイルなどのオプションを持つ、ひな型プラグインを作成します。
もちろん、これらや他のものの異なる要素を取り入れて、独自のボイラープレートも作成できます。