Наследовать статические свойства в подклассе без redeclaration?

У меня есть та же проблема как этот парень с приложением, которое я пишу прямо сейчас. Проблема состоит в том, что статические свойства не наследованы в подклассах, и поэтому если я использую помехи:: ключевое слово в моем основном классе, это устанавливает переменную в моем основном классе также.

Это работает, если я повторно объявляю статические переменные в своем подклассе, но я ожидаю иметь большое количество статических свойств и подклассов и хотеть избежать дублирования кода. Ответ с самым высоким рейтингом на странице, которую я связал, имеет ссылку на несколько "обходных решений", но это, кажется, имеет 404'd. Кто-либо может предоставить мне некоторую справку или возможно указать на меня в направлении упомянутых обходных решений?

14
задан Community 23 May 2017 в 11:59
поделиться

1 ответ

Я не уверен, о каком конкретном обходном пути идет речь, я могу придумать довольно много из них, которые могут сработать. Я лично не стал бы использовать их ни в каком коде. Я бы порекомендовал вам взглянуть на Возможно ли чрезмерное использование позднего статического связывания в PHP? и еще раз подумать, есть ли лучший способ сделать то, чего вы надеетесь достичь.

Также имейте в виду, что мой код полностью не протестирован, поскольку я написал его только здесь.

Метод 1: Всегда используйте массив для вычисления

Все остальные методы основаны на этом. Где бы вы ни использовали статическое свойство, вы вставляете код для определения класса и его получения. Я бы рассмотрел это только в том случае, если вы никогда не планируете использовать собственность где-либо еще.

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

Метод 2: Используйте методы получения / настройки

Если вы планируете использовать его более чем в одном месте, этот метод будет лучше. В некоторых шаблонах singleton используется аналогичный метод.

<?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;
    }
}

Метод 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;
        }
    }
}
8
ответ дан 1 December 2019 в 16:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: