Detailed description of static binding usage after php5.3 and php5.3

Source: Internet
Author: User

Detailed description of static binding usage after php5.3 and php5.3

This example describes static binding after php5.3. We will share this with you for your reference. The details are as follows:

Original manual:

Since PHP 5.3.0, PHP has added a function called static binding later,Class used to reference static calls within the inheritance scope.

To be precise, static binding is used to store the Class Name of the previous non-forward call. When a static method is called, the class name is the one explicitly specified (usually on the left side of the: Operator). When a non-static method is called, that is, the class to which the object belongs. The so-called "Forward call" (forwarding call) refers to the static call through the following methods: self ::, parent ::, static :: and forward_static_call (). Use the get_called_class () function to obtain the Class Name of the called method. static: indicates its range.

This function is named "static binding later" from the perspective of the language ". "Post-binding" means that static: is not resolved to define the class of the current method, but calculated during actual operation. It can also be called "static binding" because it can be used for (but not limited to) Calling static methods.

Self: Restrictions

Using self: Or _ CLASS _ for static reference to the current CLASS depends on the CLASS where the current method is defined:

Example #1 self: Usage

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

Static binding later: static binding later: I wanted to introduce a new keyword to indicate the class originally called at runtime to bypass the restriction. Simply put, this keyword allows you to reference the Class B rather than A when calling test () in the preceding example. The final decision is not to introduce new keywords, but to use reserved static keywords.

Example #2 static: simple usage

<? Phpclass A {public static function who () {echo _ CLASS __;} public static function test () {static: who (); // later static binding starts here} 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 called class is the class to which the object instance belongs. Because $ this-> tries to call a private method within the same scope, static: may give different results. Another difference is static: can only be used for static attributes.

Example #3 use static in a non-static environment ::

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

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

Note: The static binding resolution will be completed until a completely resolved static call is obtained. If the static call uses parent: Or self:, the call information is forwarded.

Example #4 forward and non-forward calls

<?phpclass 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 the class that solves the problem of referencing static calls within the inheritance scope based on the PHP static binding function later.

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, because self: Depends on the class in the definition, rather than the class in the running. To solve this problem, you may rewrite the status () method in the inheritance class. A better solution is to add the static binding function after PHP 5.3.

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: does not point to the current class. In fact, it is calculated during running, and all attributes of the final class are forcibly obtained.

Therefore, we recommend that you do not use self: or static: in the future ::

Supplement:

Post 1

Php static binding later, how to explain? The following figure Outputs A, C, and C.

It can be seen from the inheritance relationship of the graph that C completely contains B and.

Before looking at the answer results, he observed that all three classes have the same name who () method.
The system will use the last one with the highest priority. Further, you can hardly use C to call the who () in A and B. You can only re-Modify the method, for example, add A getBWho () {echo B: who ();}
Then call who () in B through C: getBWho ();

The running result is as follows:

Test only appears in B, so the result must be three results run in test:

First, the static function in A is called directly by the name of the static name. There is no suspense, it must be
Second: parent: is the parent class at the upper level. In this question, it is A, and A directly calls static: who (); As mentioned above, this who () the highest priority is in C. No matter where you call it in ABC, as long as it is static: who (), it must be the final definition. The coverage effect, if you want to call A in A, you must specify A: who () or remove static from scope restrictions. Therefore, this who () is the who defined in C.
Third: self: who is similar to the second one. If we look at B, we should pay attention to the coverage effect. To call the who in B, we must B: who (), because the more advanced C has rewritten this method, if C does not have the who, it must be B, and so on. Therefore, it is necessary to call who in C;

The answer is ACC.

The Code is as follows:

<?phpclass 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();?>

Output: A B

Post 2

(For the code shown above)

Isn't the manual clear?

"Post-binding" means that static: is not resolved to define the class of the current method, but calculated during actual operation. It can also be called "static binding" because it can be used for (but not limited to) Calling static methods.

#1 there is a small problem

[Self: foo (); // This self is actually a C class. Do you understand? C: test () C inherits the test () method of B]

Inaccurate. self is still Class B, but it does not overwrite the foo method. Therefore, the foo method of the parent class A is called.

If self is actually a class C, try to change self: foo (); to self: who ();. Print C, but print B, this is exactly the difference between self and static.

<?phpclass 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::who();}public static function who() {echo __CLASS__."\n";}}class C extends B {public static function who() {echo __CLASS__."\n";}}C::test();?>

Output: A C B

Post 3

A: foo (); // A refers to Class A. Access the foo method of Class A and the who method parent: foo (); // call the foo method of Class B's parent class -- A and tell the original caller of the foo method Cself: foo (); // self refers to the class that defines the method, b, but B does not define the foo method. It passes the original caller C up, // accesses the foo method of the parent class, and finally accesses the who METHOD OF c;

So I answered the question above: IF self: foo (); is changed to self: who (), because self refers to B, and B has the who method, so the result is B.

Static call uses parent: Or self: to forward original call Information.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.