Home  >  Article  >  Backend Development  >  Detailed explanation of the definition and usage examples of PHP post-static binding

Detailed explanation of the definition and usage examples of PHP post-static binding

伊谢尔伦
伊谢尔伦Original
2017-07-17 16:16:451517browse

Original text of the manual: Since PHP 5.3.0, PHP has added a feature called late static binding, used for reference within the inheritance scope Classes that are called statically.

The working principle of late static binding is to store the class name in the previous "non-forwarding call" (non-forwarding call). When making a static method call, the class name is the one explicitly specified (usually on the left side of the :: operator); when making a non-static method call, it is the class to which the object belongs. The so-called "forwarding call" refers to static calls made in the following ways: self::, parent::, static:: and forward_static_call(). You can use the get_called_class() function to get the class name of the called method, and static:: points out its scope.

This feature is named "late static binding" from a language internal perspective. "Late binding" means that static:: is no longer resolved to the class in which the current method is defined, but is calculated at actual runtime. It can also be called "static binding" because it can be used for (but is not limited to) calls to static methods.

Limitations of self::

Use self:: or __CLASS__ for a static reference to the current class, depending on the class in which the current method is defined:

Example #1 self:: Usage


<?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 routine will output:

A

Usage of late static binding later Static binding was intended to circumvent the limitation by introducing a new keyword representing the class that was initially called at runtime. Simply put, this keyword allows you to refer to class B instead of A when calling test() in the above example. It was finally decided not to introduce new keywords, but to use the already reserved static keyword.

Example #2 static:: Simple usage


<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期静态绑定从这里开始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>

The above routine will output:

B

Note: In a non-static environment, the class called is the class to which the object instance belongs. Since $this-> will try to call the private method in the same scope, static:: may give different results. Another difference is that static:: can only be used with static properties.

Example #3 Using static::


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

in a non-static environment will output:

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

Note: Late static binding The parsing will continue until a fully resolved static call is obtained. On the other hand, if called statically using parent:: or self:: the calling information will be forwarded.

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 routine will output:

A
C
C

The following example analyzes a class that references static calls in the inheritance scope based on PHP's late static binding function.

First look at the following code:


class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is alive

Obviously, the result is not what we expected. This is because self:: depends on the class in which it is defined. rather than the running class. In order to solve this problem, you may override the status() method in the inherited class. A better solution is that PHP 5.3 added the function of late static binding.

The code is as follows:


class Person
{
public static function status()
{
static::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is deceased

It can be seen that static:: no longer points to the current class. In fact, it is calculated during operation and is forced to be obtained. All properties of the final class.

Therefore, it is recommended that you do not use self:: in the future and use static::

The above is the detailed content of Detailed explanation of the definition and usage examples of PHP post-static binding. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn