PHP无法覆盖受保护的静态

时间:2011-05-28 23:00:06

标签: php

我似乎无法覆盖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
?>

4 个答案:

答案 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)

实际上你可以覆盖它们:)

你不能在父类中使用它们,因为它们是静态的。后期静态绑定修复了它。