我似乎无法覆盖protected static
个变量。考虑到你也不能覆盖任何私有变量,这是相当烦人的。我怎么解决这个问题? (必须支持PHP 5.2)
<?
class Foo{
protected static $stuff = 'Foo';
public function showStuff(){
echo self::$stuff . PHP_EOL;
}
}
class Bar extends Foo{
protected static $stuff = 'Bar';
}
$f = new Foo();
$b = new Bar();
$f->showStuff(); // Output: Foo
$b->showStuff(); // Output: Foo
?>
答案 0 :(得分:17)
您需要使用PHP {5.3}中引入的功能late static bindings。在您的班级Foo
中,self
指的是Foo
班级。您想要引用呼叫发起的类。您需要使用关键字static
:
<?
class Foo{
protected static $stuff = 'Foo';
public function showStuff(){
echo static::$stuff . PHP_EOL; // <-- this line
}
}
class Bar extends Foo{
protected static $stuff = 'Bar';
}
$f = new Foo();
$b = new Bar();
$f->showStuff(); // Output: Foo
$b->showStuff(); // Output: Bar
?>
答案 1 :(得分:3)
您可以覆盖它们,但无法从父类中获取值。好吧,这是wat PHP调用覆盖,而它实际上重新引入变量并试图隐藏父变量。这就是为什么这不会按你想要的方式工作。
由于你还没有使用5.3,我认为最好的解决方案是使用(和覆盖)静态函数。如果您不需要修改该值,则可以使该类重写该函数,以使其为每个类返回不同的常量值。如果确实需要变量,可以在每个类中重新引入变量和函数。
class x
{
static $a = '1';
static function geta()
{
return self::$a;
}
}
class y extends x
{
static $a = '2';
static function geta()
{
return self::$a;
}
}
echo x::geta();
echo y::geta();
它很脏,但它解决了这个问题,直到你可以使用PHP 5.3的整齐static::
方式。
答案 2 :(得分:1)
有一个更好的解决方案。您可以使用get_called_class()
查找当前上下文并使用它来访问静态。
例如
class Foo {
protected static $table = "foo";
static function getTable() {
$class = get_called_class();
return $class::$table;
}
}
class Bar extends Foo {
protected static $table = "bar";
}
echo Foo::getTable()."<br />\n";
echo Bar::getTable()."<br />\n";
您将获得如下输出:
foo<br />
bar<br />
这适用于任何PHP 5版本
答案 3 :(得分:0)
实际上你可以覆盖它们:)
你不能在父类中使用它们,因为它们是静态的。后期静态绑定修复了它。