web-dev-qa-db-ja.com

クラスインスタンスのみにフィルタを追加する方法はありますか

私はそれを拡張するいくつかのケースで使用するカスタムクラスを持っています、例えば

class A {
    public function show_things() {
        print_r( apply_filter( 'yet_another_filter', array( 'coffee', 'tea' ) ) );
    }
}

class B extends A {
    public function __construct() {
        parent::__construct();
        add_filter( 'yet_another_filter', array( $this, 'other_things' ) );
    }

    public function other_things( $things ) {
        return array( 'crisps', 'beer' );
    }
}

class C extends A {
    public function __construct() {
        parent::__construct();
        // no filter added here
    }
}

それでは、クラスBとCのインスタンスを作成します。

$b = new B;
$c = new C;

$bのことを表示するとき、

$b->show_things(); // gives crisps, beer

フィルタを追加しなかったインスタンス$cのものを表示すると、インスタンス$bによって追加されたフィルタは 'global'なので、同じ結果が得られます。

$c->show_things(); // gives crisps, beer, which is logical

しかし、 コーヒーと紅茶を飲みたい 、クラスC内にフィルタを追加しなかったので、フィルタを追加してから$thisを確認するときにインスタンス自体を追加する必要がありますかそれとも別の(より良い)アプローチはありますか?

4
uruk

問題はWordPressのフィルタがグローバルであるということです。フィルタをどこかに追加しても、それを削除しない限り、どこにでも存続します。

また、 継承オーバーコンポジション を優先し、現在のアプリケーション構造が既に継承に基づいて構築されていて、それを変更できない場合、または変更したくない場合は、少なくとも次のことにフィルタを使用しないでください。グローバルではありません。

データを返すロジックからデータを返すロジックを分離することで、すべてがはるかに簡単になります。

class A {

    function get_things() {
        return array( 'coffee', 'tea' );
    }

    function show_things() {
        return apply_filter( 'yet_another_filter', $this->get_things() );
    }

}

class B extends A {

    function get_things() {
        return array( 'crisps', 'beer' );
    }

}

class C extends A {

}

あなたが推測できるように:

$a = new A;
$b = new B;
$c = new C;

$a->show_things(); // array( 'coffee', 'tea'  )
$b->show_things(); // array( 'crisps', 'beer'  )
$c->show_things(); // array( 'coffee', 'tea'  )

すべての結果は"yet_another_filter"フィルタを通過するため、外部コードがすべての場合に結果を上書きすることができます。これがフィルタの目的です。

5
gmazzap