首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Late Static Bindings

As of PHP 5.3.0, PHP implements a feature called late static bindings which can be used to reference the called class in a context of static inheritance.

More precisely, late static bindings work by storing the class named in the last "non-forwarding call". In case of static method calls, this is the class explicitly named (usually the one on the left of the :: operator); in case of non static method calls, it is the class of the object. A "forwarding call" is a static one that is introduced by self::, parent::, static::, or, if going up in the class hierarchy, forward_static_call(). The function get_called_class() can be used to retrieve a string with the name of the called class and static:: introduces its scope.

This feature was named "late static bindings" with an internal perspective in mind. "Late binding" comes from the fact that static:: will not be resolved using the class where the method is defined but it will rather be computed using runtime information. It was also called a "static binding" as it can be used for (but is not limited to) static method calls.

Limitations of self::

Static references to the current class like self:: or ___CLASS___ are resolved using the class in which the function belongs, as in where it was defined:

Example #1 self:: usage

代码语言:javascript
复制
<?php
class?A?{
????public?static?function?who()?{
????????echo?__CLASS__;
????}
????public?static?function?test()?{
????????self::who();
????}
}

class?B?extends?A?{
????public?static?function?who()?{
????????echo?__CLASS__;
????}
}

B::test();
?>

The above example will output:

代码语言:javascript
复制
A

Late Static Bindings' usage

Late static bindings tries to solve that limitation by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow you to reference B from test() in the previous example. It was decided not to introduce a new keyword but rather use static that was already reserved.

Example #2 static:: simple usage

代码语言:javascript
复制
<?php
class?A?{
????public?static?function?who()?{
????????echo?__CLASS__;
????}
????public?static?function?test()?{
????????static::who();?//?Here?comes?Late?Static?Bindings
????}
}

class?B?extends?A?{
????public?static?function?who()?{
????????echo?__CLASS__;
????}
}

B::test();
?>

The above example will output:

代码语言:javascript
复制
B

Note: In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope, using static:: may give different results. Another difference is that static:: can only refer to static properties.

Example #3 static:: usage in a non-static context

代码语言:javascript
复制
<?php
class?A?{
????private?function?foo()?{
????????echo?"success!\n";
????}
????public?function?test()?{
????????$this->foo();
????????static::foo();
????}
}

class?B?extends?A?{
???/*?foo()?will?be?copied?to?B,?hence?its?scope?will?still?be?A?and
????*?the?call?be?successful?*/
}

class?C?extends?A?{
????private?function?foo()?{
????????/*?original?method?is?replaced;?the?scope?of?the?new?one?is?C?*/
????}
}

$b?=?new?B();
$b->test();
$c?=?new?C();
$c->test();???//fails
?>

The above example will output:

代码语言:javascript
复制
success!
success!
success!


Fatal error:  Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

Note: Late static bindings' resolution will stop at a fully resolved static call with no fallback. On the other hand, static calls using keywords like parent:: or self:: will forward the calling information. Example #4 Forwarding and non-forwarding calls <?php class?A?{ ????public?static?function?foo()?{ ????????static::who(); ????} ????public?static?function?who()?{ ????????echo?\_\_CLASS\_\_."\n"; ????} } class?B?extends?A?{ ????public?static?function?test()?{ ????????A::foo(); ????????parent::foo(); ????????self::foo(); ????} ????public?static?function?who()?{ ????????echo?\_\_CLASS\_\_."\n"; ????} } class?C?extends?B?{ ????public?static?function?who()?{ ????????echo?\_\_CLASS\_\_."\n"; ????} } C::test(); ?> The above example will output: A C C

← Type Hinting

Objects and references →

代码语言:txt
复制
 ? 1997–2017 The PHP Documentation Group

Licensed under the Creative Commons Attribution License v3.0 or later.

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com