抽象父类中的PHP静态变量:问题在示例代码中!

时间:2011-04-01 12:40:02

标签: php oop static parent-child

包含问题的快速代码:

abstract class ClassParent {
    public static $var1 = "ClassParent";
}

class ClassChild1 extends ClassParent{
    public static function setvar1(){
        ClassChild1::$var1 = "ClassChild1";     
    }
}

class ClassChild2 extends ClassParent{
    public static function setvar1(){
        ClassChild2::$var1 = "ClassChild2";
    }
}


ClassChild1::setvar1();

echo ClassChild2::$var1;
// Returns "ClassChild1". Shouldn't this still be "ClassParent"?

我假设上面是预期的行为而不是PHP错误。在这种情况下,我怎么能在父类中声明一个静态变量,它将为子类单独处理。换句话说,我想要具有单独的静态值PER CHILD CLASS。我必须在子类中特别声明静态变量,还是有另一种方式?

谢谢!

2 个答案:

答案 0 :(得分:16)

编辑:在进一步调查中,我认为即使是后期静态绑定,你所要求的也不是直接可能的。实际上,我有点惊讶。

The answer to this question提供了一些解决方法。

原始答案:


在父类中,如果您在表单中引用静态变量:

self::$var

它将在所有继承的类中使用相同的变量(因此所有子类仍将访问父类中的变量)。

这是因为self关键字的绑定是在编译时完成的,而不是在运行时完成的。

从PHP 5.3开始,PHP使用static关键字支持后期静态绑定。因此,在您的课程中,请参考以下变量:

static::$var

'static'将在运行时解析为子类,因此每个子类都有一个单独的静态变量。

答案 1 :(得分:3)

感谢您提出这个问题!我遇到了一些我无法追踪的问题,这帮助我解决了这些问题。 :)

您可能有兴趣知道此行为有bug report,其中包含解决方法。在你的情况下,这将是:

class ClassChild1 extends ClassParent{
    public static function setvar1(){
        $tmp = 'x';
        static::$var1 =& $tmp; // break reference
        // and now this works as expected: (changes only ClassChild1::$var1)
        static::$var1 = "ClassChild1";     
    }
}
// do the same in ClassChild2...

丑陋,我同意 - 但PHP以这种方式按预期工作,加上它没有副作用。

这确实是我眼中一个非常值得怀疑的(并且记录不完整的)“特征” - 让我们希望有一天能改变它。