我有一个自定义类,用于扩展它,例如
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
是“全局的”:
$c->show_things(); // gives crisps, beer, which is logical
但是
I would like to get the coffee and tea, 由于我没有在类C中添加过滤器。在添加过滤器并检查
$this
? 还是有其他(更好的)方法?
最合适的回答,由SO网友:gmazzap 整理而成
问题是WordPress中的过滤器是全局的;如果在某个地方添加过滤器,除非将其删除,否则它会一直存在。
同时考虑您应该composition over inheritance, 如果您当前的应用程序结构已经构建在继承的基础上,并且您不能或不想更改它,那么您至少应该避免对非全局的内容使用过滤器。
通过将返回数据的逻辑与过滤数据的逻辑分离,一切都变得更加简单:
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"
过滤器,允许外部代码在所有情况下覆盖结果,这就是过滤器的用途。