Подтвердить что ты не робот

Расширение статических классов PHP

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

Скажем, у нас есть суперкласс (называемый "Супер" ) и подкласс (называемый "Sub" ).

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo self::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

Теперь вы, вероятно, ожидаете, поскольку Sub расширяет Super, этот Sub теперь наследует все методы Super, однако, похоже, он получает только ссылки на методы Sub.

Я говорю это, потому что, если я звоню:

Sub::get_class_name();

вывод "Super", а не "Sub".

И если я звоню:

Sub::get_title();

снова, вывод "супер", и у меня даже есть заголовок $, объявленный в Sub.

Таким образом, это означает, что когда я вызываю унаследованную статическую функцию, область функций будет суперклассом, а не тем, на который вызывается (даже если вы печатаете обратную трассировку, это покажет, что вызов был сделан на суперклассе!!!), и для того, чтобы получить область видимости в качестве подкласса, на который делается вызов, мне нужно обновить этот метод внутри этого подкласса. Хорошо, этот вид побеждает цель расширения классов, не так ли?

Итак, мой вопрос: могу ли я когда-либо расширить статический класс, вызвать один из унаследованных методов и обладать областью подкласса? или, по крайней мере, иметь возможность идентифицировать это имя класса? И если нет, то почему я хотел бы расширить статические классы?

Спасибо!

4b9b3361

Ответ 1

Опять же, это невозможно до PHP 5.3.0.

Поздняя статическая привязка была представлена ​​в PHP 5.3.0 и позволяет вам делать именно то, что вы хотите с помощью static.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

get_class_name() по-прежнему будет возвращать Super, хотя __CLASS__ всегда возвращает текущий класс, который объявляется запущенным способом (вроде как __FILE__, который всегда возвращает текущий файл независимо от того, включил ли вы его или нет).

Для этого у вас нет выбора, кроме как повторно объявить функцию в классе Sub.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';

    public static function get_class_name()        
    {
        echo __CLASS__;
    }
}

Ответ 2

Вы можете использовать get_called_class(), чтобы получить имя класса вызываемого класса, даже если оно статично. Вам не нужно нигде объявлять его.

Из примера Andrew:

class Super {
    public static function get_class1_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo get_called_class();
    }

}
class Sub extends Super {    
    public static function get_class2_name()        
    {
        echo __CLASS__;
    }

}
Sub::get_title(); // Echos Sub.
Sub::get_class1_Name(); // echos super
Sub::get_class2_Name(); // echos sub

Поэтому вам не нужно объявлять какие-либо переменные.

Ответ 3

К счастью, я что-то делаю для меня, поэтому я сказал, вверните его, я использую PHP5.3. Но даже в этом случае мне не нравится, что я должен обновлять "get _class _name" в каждом классе, возможно, я расширяюсь, как 10 классов. Поэтому я придумал это решение:

class Super {
    protected static $classname = __CLASS__;
    public static function get_classname($name)
    {
        static::$classname = $name;
    }
    public static function get_classname()
    {
        return static::$classname;
    }
}
class Sub1 extends Super { }
class Sub2 extends Super { }
class Sub3 extends Super { }

$classes = get_declared_classes();
foreach($classes as $k => $v)
{
    if (is_subclass_of($v, 'Super'))
    {
        $v::set_classname($v);
    }
}

echo Sub1::get_classname(); // Sub1
echo Sub2::get_classname(); // Sub2
echo Sub3::get_classname(); // Sub3

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