web-dev-qa-db-ja.com

匿名コールバックでOOPを使用している場合にWordpressのアクション/フィルタをキャンセルする方法

私が見つけたワードプレスプラグインのほとんどはfunctions basedです、例えば、公式のakismetプラグイン

function akismet_init() {
    global $wpcom_api_key, $akismet_api_Host, $akismet_api_port;


    // ...
}
add_action('init', 'akismet_init');

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

  • 関数間で状態を共有することはできないので、グローバル変数を使用する必要があります
  • 単体テストを行うのが難しい、つまりモックする方法がない

私の最初の試みはオブジェクトにラップすることです。 akismet.php

class Akismet {

    protected static $akismet_api_Host;
    protected static $akismet_api_port;

    public function __construct()
    {
        add_action('init', array($this, 'init'));
    }

    public function init()
    {
       // Do my init here
    }
}

$GLOBALS['Akismet'] = new Akismet();

しかし、このアプローチにはまだいくつかの問題があります

  • 呼び出し可能にするには、自分のメソッドのほとんどをパブリックとして公開する必要があります(これは悪いです)。
  • 匿名コールバックを使用せずにコールバックに変数を渡すことはできません(匿名コールバックを使用する場合は、remove_action/remove_filterを使用してそれらを削除することはできません)

例えば.

public function __construct()
{
    $foo = 'bar';
    add_action('init', function() use ($foo) {
      echo $foo; // You can pass variable by using callback but you cannot this action later!
    });
}

それでは、どのようにしてWordpressのアクション/フィルタに変数を渡す柔軟性を持たせながら、後でそれらをキャンセルする柔軟性を維持するのでしょうか。

1
Yoga

1つの方法はクラスとオブジェクトを使うことです。再利用性、共同作業などを考慮すると、より効率的です。自分がしていることがわかっていれば、グローバル変数を使うのは悪いことではないと思います。

それで私はあなたにOOP(オブジェクト指向プログラミング)、特に継承と多態性を使うことを勧めます。

1
JMau

それでは、どのようにしてWordpressのアクション/フィルタに変数を渡す柔軟性を持たせながら、後でそれらをキャンセルする柔軟性を維持するのでしょうか。

あなたはクラスのプロパティの一つに関数を代入することができます:

public function __construct()
{
    $foo = 'bar';

    $this->init_func = function() use ( $foo ) {
        echo $foo;
    };

    add_action( 'init', $this->init_func );
}

その後、あなたはこれを行うことができます:

remove_action( 'init', $this->init_func );

しかし、そうしないでください。

テストが悪夢になると思います。また、あなたはクラスにいます。そこでは、あなたが関数で使いたい値をプロパティに割り当てることができます:

public function __construct()
{
    $this->foo = 'bar';

    add_action( 'init', array( $this, 'init' ) );
}

public function init()
{
    echo $this->foo;
}

それがクラスの目的のようなものです。 :-)


あなたはパブリッククラスのメソッドを持つことを恐れているようです。どうして? WordPressにあなたのクラスのコードを呼び出せるようにしたいので、それを可能にするパブリックAPIが必要です。 PHPクラスはpublicメソッドを提供していますので、ホイールを再発明するのではなく、それらを使用することもできます。 :-)

1
J.D.