In PHP, variables are stored in the hash table, called the variable symbol table. The variable name is the key of the hash table, and the zval pointer of the container corresponding to the variable name is the value in the hash table. All global variables are placed in a primary symbol table (that is, the hash table corresponding to the array $ globals ). PHP has a feature. When a variable is named, the $ variable identifier cannot start with a number. For example, in the following code:
<? PHP
$111 = "my ";
?>
The following error is reported: Parse error: syntax error, unexpected t_lnumber, expecting t_variable or '$' in...
From the error description, This Is A syntax error. Therefore, we infer that the legitimacy of the variable name should be determined in the syntax analysis phase during compilation.
To prove our point of view, we can try to define a variable starting with a number character in the execution phase:
<? PHP
$ A = 111;
$ A = "my"; // use the value of $ A as the variable name
Echo $;
Var_dump ($ globals );
?>
No error is reported after running, and related symbols are found in the global symbol table $ globals:
["A"] =>
INT (111)
[& Quot; 111 & quot;] = & quot;>
String (2) "my"
In this way, we define a variable named by full-digit characters, which seems to be against the PHP rules, but does.
(Readers can try to output the value of $ globals ["111"]. Although there is a value, the result is null. This is a type conversion feature in PHP)
In this Code, the $ A = "my" statement has polymorphism. Only when this statement is actually executed can we determine the variable name, PHP cannot know what the variable name will be during the syntax analysis phase, so no error is reported. In the execution phase, PHP does not judge the legitimacy of the variable name, so a rebellious variable is generated.
After knowing this feature, we will immediately think of another special variable: $ this
In the class method, the $ this keyword is used to point to the object instance of the current class. If you assign a value to $ this, what will happen?
<? Php <br/> class person <br/> {<br/> protected $ _ name = "phper"; </P> <p> protected $ _ age = 18; </P> <p> Public Function getname () <br/>{< br/> $ this = 123; <br/> return $ this-> _ name; <br/>}</P> <p> Public Function getage () <br/>{< br/> return $ this-> _ age; <br/>}</P> <p> $ P = new person (); <br/> $ p-> getname (); <br/>?>
Run the code and report the following error:
Fatal error: cannot re-assign $ this in...
PHP has implemented some protection measures for the $ this variable, but this protection measure is not completely. We use the previous method to change the value of $ this during the execution period, and the modified getname method is:
Public Function getname () <br/>{< br/> $ A = "this"; <br/>$ $ A = 123; <br/> echo $ this; <br/> return $ this-> _ name; <br/>}
Then execute the code and find that the code can be executed smoothly. The value of $ this is changed to 123. Therefore, we can judge that the protection for the $ this keyword is limited to the syntax analysis stage.
When the value of $ this changes to 123, it is reasonable to say that $ this-> _ name will certainly report an error, but the code can be executed normally, which is indeed incredible. Thus, it is inferred that
The reference method like $ this-> _ name differs from the reference method of common object variables. We will continue to modify getname:
Public Function getname () <br/>{< br/> $ A = "this"; <br/>$ $ A = 123; <br/> $ B = 123; <br/> echo $ this; <br/> echo $ B; <br/> $ this-> getage (); <br/> $ B-> getage (); <br/> return $ this-> _ name; <br/>}
In this Code, the values of $ this and $ B are equal to 123, but $ this-> getage () can be executed smoothly, but $ B-> getage () returns an error:
Fatal error: call to a member function getage () on a non-object...
This is a strange problem. we can infer that the op handler corresponding to $ this-> getage () and $ B-> getage () must be different after compilation.
View op information through VLD
$ This-> getage () corresponds:
Zend_init_method_call res [is_unused] OP1 [is_unused] OP2 [is_const (8142027) 'getage']
$ B-> getage () corresponds:
Zend_init_method_call res [is_unused] OP1 [is_cv! 0] OP2 [, is_const (8142039) 'getage']
Although it corresponds to the same op code, but because of the different operands (the former does not use OP1, the latter uses OP1, and the value of OP1! 0 indicates $ B). The same op Code corresponds to a handler of the same class, and then a handler of this class is determined based on the type of the operand.
The handler corresponding to $ this-> getage () is processed as zend_init_method_call_spec_unused_const_handler.
$ B-> handler corresponding to getage (): zend_init_method_call_spec_cv_const_handler
This is their difference.
$ My = new person ();
$ Name = $ my-> getname ();
When getname is called, the scope of getname () has been set to $ name. During syntax analysis, $ this-> getage () in getname is () this call only calls the getage () function in the current scope, regardless of the specific value of $ this. In calls such as $ B-> getage, the value corresponding to $ B is concerned.