php late static binding

伊谢尔伦
Release: 2016-11-23 13:51:27
Original
1034 people have browsed it

Since PHP 5.3.0, PHP has added a feature called late static binding, which is used to reference statically called classes in the inheritance scope.

To be precise, the working principle of late static binding is to store the class name in the previous "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 parsed into 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.

Self:: Limitations

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();
?>
Copy after login

The above routine will output:

A
Copy after login

Usage of late static binding

Late static binding was intended to circumvent the restriction by introducing a new keyword to represent the class 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();
?>
Copy after login

The above routine will output:

B
Copy after login

Note:

In a non-static environment, the called class is the class to which the object instance belongs. Since $this-> will try to call private methods 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
?>
Copy after login

in a non-static environment The above routine will output:

success!
success!
success!
Fatal error:  Call to private method C::foo() from context &#39;A&#39; in /tmp/test.php on line 9
Copy after login

Note:

The analysis of later static binding will continue until a fully resolved static call is obtained. On the other hand, if a static call is made using parent:: or self:: the call 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();
?>
Copy after login

The above routine will output:

A
C
C
Copy after login


Related labels:
php
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template