web-dev-qa-db-ja.com

プラグインAPIにフィルタとアクションを使用しますか?

私が開発したプラグインにパブリックAPIを統合したいです。

他のプラグインがAPIを統合する通常の方法は、任意のテーマまたはプラグインから呼び出すことができるいくつかの関数を定義することです。

しかし、私のAPIプラグインがアクティブでないときにエラーが発生するので、これは悪い考えだと思います。そして、私はAPIにフィルタとアクションを使用するという考えを思い付きました。こんな感じです

// Get some user specific data from my plugin:
$data = false;
if ( apply_filters( 'mp:is-active' ) ) {
    $data = apply_filters( 'mp:get-user-data' );
}

// Add a private notification for a single user:
do_action( 'mp:send-notification', $user_id, $message );

質問は:

私はまだ他のプラグインでこの種のAPIを見たことがないので、それを使用しない正当な理由があります(例えば悪いパフォーマンスなど)

それともこれは良い方法だと思いますか?

5
Philipp

確かにこのアプローチにはいくつかの利点がありますが、いくつかの問題もあります。

使い方はそれほど簡単ではありません

あなたのプラグインのターゲットがWordPressの開発者であれば、彼らはプラグインAPIに非常に精通しているでしょうが、エンドユーザーはそうではありません。

開発者以外にとっては、次のようになります。

$data = give_me_the_data();

理解すること、覚えること、タイプすることのほうが簡単です。

$data = apply_filters( 'give_me_the_data' );

このサイトの質問をいくつか見れば、初心者と非開発者の間でWordPressのアクションとフィルタに関してどの程度の混乱があるのか​​理解できます。

「タイプミス」問題

多くのタイプミスをする人として、私は彼らがイライラしていることを知っています。あなたがタイプミスで関数を書くならば、それはエラーを投げそしてユーザは直ちに問題を認識します。アクション名にタイプミスがあるとAPIは失敗しますが、認識するのはかなり困難です。

例として:

$data = apply_filters('mp:get-user-data'); // works

$data = apply_filters('mo:get-user-data'); // does not work, hard to find why

$data = mp_get_user_data(); // works

$data = mo_get_user_data(); // does not work and throws an error, immediately found

グローバル地獄

アクションとフィルタは単なるグローバル変数です。あなたがあなたのAPIを構築するためにそれらを使うならば、あなたのコードはシステムに存在するコードの他の1つの他の行によって仕上げることができます。

これは、誰が知っているかを問わず、どのプラグインでもプラグインが失敗する可能性があるという明らかな理由がないことを意味します。そしてその理由はあなたのプラグインが失敗することではないということです。

例:

do_action( 'mp:send-notification', $user_id, $message );

// somewhere else
add_action( 'all', 'do_something_bad_that_makes_your_plugin_fail');

さらに、誰でもこれらのフックを使用することができ、それがあなたのAPIに多くの柔軟性をもたらすかもしれないとしても、それはまた多くの複雑さをもたらします。

たとえば、引数としてオブジェクトを使用している場合、それらは参照によって渡されるオブジェクトであり、コールバックが実行される前にそれらが変更される可能性があります。

結論

これらが私の頭に浮かぶすべての理由ですが、このアプローチが広く使用されていない場合は多分他の理由があります。

私にとっては、特に最後の点ではこのアプローチを使用しませんが、WordPressのコンテキストでは絶対に間違っているとは言えません。

ですから私は、あなたがそれを使うことを強くお勧めしたくありません。すべての問題を前もって検討することを提案するだけです。いったんあなたが公にAPIを公開したら、切り替えるのは非常に難しいからです。

5
gmazzap

両方のアプローチは相互に排他的ではありません。 @gmazzapが言ったように、コールバック地獄を作成しないでください。

しかし、あなたは初期フックを提供することができるので、他の開発者はかなり遅いfunction_exists()チェックに頼る必要はありません。

あなたのプラグインで、他の開発者があなたのクラスや関数を安全に呼び出すために使用できるフックを提供してください。

add_action( 'wp_loaded', [new Your_Plugin_Bootstrap, 'setup' ], 0 );

class Your_Plugin_Bootstrap {

    public function setup() {

        // set up your data and the auto-loader, then:
        do_action( 'your_plugin_loaded' );
    }
}

現在、サードパーティの開発者はそのフックを使用して「通常の」PHPに進むことができます。

add_action( 'your_plugin_loaded', function() {

    // safely use your plugin's classes here.
});

MultilingualPress でそれを行い、他の開発者からのフィードバックはこれまで非常に良かったです。理解するのは簡単です、そしてあなたはたった一つのフックを学ぶ必要があります。

私のプラグイン用のAPIを作成するにはどうすればいいですか?

6
fuxia