Что такое поздние статические привязки в PHP?
Что такое поздние статические привязки в PHP?
7 ответов:
начиная с PHP 5.3.0, PHP реализует функцию late static binding, которая может использоваться для ссылки на вызываемый класс в контексте статического наследования.
поздняя статическая привязка пытается решить это ограничение, введя ключевое слово, которое ссылается на класс, который был первоначально вызван во время выполнения. Было решено не вводить новое ключевое слово, а использовать
static
это уже было зарезервировано.давайте посмотрим пример:
<?php class Car { public static function run() { return static::getName(); } private static function getName() { return 'Car'; } } class Toyota extends Car { public static function getName() { return 'Toyota'; } } echo Car::run(); // Output: Car echo Toyota::run(); // Output: Toyota ?>
late static bindings
работа путем хранения класса, названного в последнем "не переадресации вызова". В случае вызовов статических методов это класс с явным именем (обычно тот, который находится слева от оператора::); в случае вызовов нестатических методов это класс объекта."переадресация вызова" является статическим, который вводится
self::
,parent::
,static::
, или, если идти вверх в иерархии классов,forward_static_call()
.функции
get_called_class()
может использоваться для получения строки с именем вызываемый класс иstatic::
вводит его объем.
вам обязательно нужно прочитать Поздние Статические Привязки в руководстве PHP. Тем не менее, я постараюсь дать вам краткое резюме.
в основном, это сводится к тому, что
self
ключевое слово не следует тем же правилам наследования.self
всегда возвращает класс, в котором он используется. Это означает, что если вы создаете метод в родительском классе и вызываете его из дочернего класса,self
не будет ссылаться на ребенка, как вы можете ожидать.поздняя статическая привязка вводит новое использование для
static
ключевое слово, которое решает эту проблемы. Когда вы используетеstatic
, Он представляет класс, где вы впервые используете его, т. е. он "привязывается" к классу времени выполнения.это две основные концепции, стоящие за ним. Кстати
self
,parent
и , когдаstatic
в игре может быть тонким, так что вместо того, чтобы идти в более подробно, я настоятельно рекомендую вам изучить примеры ручной страницы. Как только вы поймете основы каждого сайта, примеры необходимы, чтобы увидеть, какие результаты вы собираетесь получить.
есть не очень очевидное поведение:
следующий код создает 'alphabeta'.
class alpha { function classname(){ return __CLASS__; } function selfname(){ return self::classname(); } function staticname(){ return static::classname(); } } class beta extends alpha { function classname(){ return __CLASS__; } } $beta = new beta(); echo $beta->selfname(); // Output: alpha echo $beta->staticname(); // Output: beta
однако, если мы удалим объявление функции classname из бета-класса, мы получим 'alphaalpha' в результате.
я цитирую из книги:"PHP Master написать ультрасовременный код".
поздняя статическая привязка была функцией, введенной с php 5.3. Это позволяет нам наследовать статические методы от родительского класса, и ссылаться вызывается дочерний класс.
это означает, что вы можете иметь абстрактный класс со статическими методами, и ссылка на конкретные реализации дочернего класса с помощью static:: method () нотации вместо самость:: метод ().
не стесняйтесь взглянуть на официальную документацию php, а также: http://php.net/manual/en/language.oop5.late-static-bindings.php
пример:
<?php class Animal { public static function StaticCall() { // Parent object invokes its own getAnimalName() // Child object invokes its own getAnimalName() instead of parent's getAnimalName() return static::getAnimalName(); } public static function SelfCall() { return self::getWeight(); } private static function getAnimalName(){ return 'Animal <br />'; } private static function getWeight(){ return '10 kg <br />'; } } class Bird extends Animal { public static function getAnimalName(){ return 'Bird <br />'; } private static function getWeight(){ return '2 kg <br />'; } } echo Animal::StaticCall(); // Animal echo Animal::SelfCall(); // 10 kg echo Bird::StaticCall(); // Bird invokes method from own object echo Bird::SelfCall(); // 10 kg invokes method from parent
в коде выше вы можете видеть два класса
Animal
, который является родительским классом иBird
, который является дочерним классом. ОбаAnimal
иBird
естьgetAnimalName()
иgetWeight()
метод. СуперклассAnimal
есть два метода:StaticCall()
иSelfCall()
.метод
StaticCall()
вызываетgetAnimalName()
С помощьюstatic
ключевое слово.
МетодSelfCall()
вызываетgetWeight()
С помощьюself
ключевое слово.вопрос, который мы теперь имеем:в каком контексте это
getAnimalName()
казнить?ответ:
static::getAnimalName()
идентифицирует контекст и вызывает метод в этом контексте.если вы вызываете
Bird::StaticCall()
код будет выполненStaticCall()
что находится вAnimal
. Тогдаstatic::getAnimalName()
будет вызывать и выполнять изBird
методgetAnimalName()
.в отличие от
self::
, потому чтоself::
всегда вызывает метод внутри объектаself
определяется. Так что еслиself::getWeight()
определяется в objectAnimal
методомSelfCall()
иBird::SelfCall()
будет называться тогдаself::getWeight()
вызываетgetWeight()
в контексте
самый простой пример, чтобы показать разницу.
Заметьте, self::$cclass A { static $c = 7; public static function getVal() { return self::$c; } } class B extends A { static $c = 8; } B::getVal(); // 7
поздняя статическая привязка, Примечание static::$c
class A { static $c = 7; public static function getVal() { return static::$c; } } class B extends A { static $c = 8; } B::getVal(); // 8