在没有重新声明的情况下继承子类中的静态属性?

Dav*_*vid 14 php inheritance static late-static-binding

我和我正在写的应用程序的这个人有同样的问题.问题是静态属性不是在子类中继承的,因此如果我在主类中使用static ::关键字,它也会在我的主类中设置变量.

如果我重新声明我的子类中的静态变量,它可以工作,但我希望有大量的静态属性和子类,并希望避免代码重复.我链接的页面上排名靠前的响应有一些指向"解决方法"的链接,但它似乎有404个.任何人都可以借给我一些帮助,或者让我指出所说的解决方法吗?

Ree*_*e45 8

我不确定它正在讨论什么具体的解决方法,我可以想到很多可行的方法.我个人不会在任何代码中使用这些.我建议你看看是否有可能在PHP中过度使用后期静态绑定?并重新考虑是否有更好的方法来做任何你希望完成的事情.

另外请记住,我的代码完全未经测试,就像我在这里写的那样.

方法1:始终使用数组来计算

所有其他方法都基于此.无论您使用静态属性,都可以插入代码来检测类并获取它.如果您从未计划在其他地方使用该物业,我只会考虑这一点.

$class = get_called_class();
if(isset(self::$_names[$class])) {
    return self::$_names[$class];
}
else {
    return static::NAME_DEFAULT;
}
Run Code Online (Sandbox Code Playgroud)

方法2:使用getter/setting方法

如果您打算在不止一个地方使用它,这种方法会更好.一些单例模式使用类似的方法.

<?php
class SomeParent {
    const NAME_DEFAULT = 'Whatever defaults here';

    private static $_names = array();

    static function getName($property) {
        $class = get_called_class();
        if(isset(self::$_names[$class])) {
            $name self::$_names[$class];
        }
        else {
            $name = "Kandy"; // use some sort of default value
        }
    }

    static function setName($value) {
        $class = get_called_class();
        self::$_names[$class] = $value;
    }
}
Run Code Online (Sandbox Code Playgroud)

方法3:__ callStatic

这是迄今为止最方便的方法.但是,您需要有一个对象实例才能使用它(__get和__set不能静态使用).它也是最慢的方法(比其他两个慢得多).我猜测,因为你已经在使用静态属性,所以这已经是一个非选择.(如果此方法适合您,如果您不使用静态属性可能会更好)

<?php
class SomeParent {

    const NAME_DEFAULT = 'Whatever defaults here';

    private static $_names = array();

    function __get($property) {
        if($property == 'name') {
            $class = get_called_class();
            if(isset(self::$_names[$class])) {
                return self::$_names[$class];
            }
            else {
                return static::NAME_DEFAULT;
            }
        }
        // should probably trigger some sort of error here
    }

    function __set($property, $value) {
        if($property == 'name') {
            $class = get_called_class();
            self::$_names[$class] = $value;
        }
        else {
            static::$property = $value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)