Что такое поздние статические привязки в 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