首页 > php面向对象 > PHP $this变量一些理解

PHP $this变量一些理解

在PHP的词法分析时,$this变量是符合其规则的,在语法解析生成中间代码时,PHP内核会根据变量类型在生成赋值的中间代码时判断是否为$this变量,如果是则报错。这里为什么要报错呢?因为this作为一个特殊的变量,在对象的成员方法等调用初始化时会将this变量添加到活动符号表。

在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

在词法分析、语法分析并生成中间代码时,$this作为一个特殊的变量存在,特别是在生成中间代码时,代码中充斥着对于this的特殊处理。这些都是为后面的运行做准备,如识别标记出某处使用this变量,在存储opcode的zend_op_array结构体中专门有一个变量this_var标识是否有this变量。一个函数或一个类方法都会生成一个新的zend_op_array,在生成中间代码时,判断当前变量是否为this变量。

this变量在执行过程中会有两种存在状态,一种是全局传递的状态,存储在EG(This),一种是当前作用域状态,以this变量存储在EG(active_symbol_table)(当前执行环境的活动符号表)。

在我们执行一个 op_array 时,比如一个对象的方法,PHP内核会给这个 op_array 生成一个 zendexecutedata ,在生成初始化时,EG(This) 会添加到EG(active_symbol_table) 。

在方法调用过程中,如果有用到this变量,则会直接取EG(active_symbol_table)的值。

那么一个对象中的EG(This)在哪里初始化呢?

就EG(This)变量本身来说,在我们初始化PHP的执行环境时,它和其它全局变量(如EG(scope)等)一样都会被初始化为NULL。

对于一个对象来说,当我们创建了一个对象,调用时,PHP内核会将当前获得的对象直接赋值给EG(This),而这个当前获得的对象是在通过new操作生成对象时创建的对象本身。

如下这个简单示例:

<?php
class Foo {
    public $var = 10;
    function t() {
        echo $this->var;
    }
    function t2() {
        echo 33;
    }
}
$foo = new Foo();
$foo->t();
?>

其主程序流程生成的中间代码如下:

function name:  (null) 
number of ops:  8 
compiled vars:  !0 = $foo 
line     # *  op                           fetch          ext  return  operands 
--------------------------------------------------------------------------------- 
2     0  >   NOP                                                       
15     1      ZEND_FETCH_CLASS                              4  :1      'Foo' 
	  2      NEW                                              $2      :1 
	  3      DO_FCALL_BY_NAME                              0           
	  4      ASSIGN                                                   !0, $2 
16     5      ZEND_INIT_METHOD_CALL                                    !0, 't' 
	  6      DO_FCALL_BY_NAME                              0           
	  7    > RETURN     
										   1this

变量原始的对象值出生在 opcode NEW,经过了赋值(ASSIGN)后,在方法初始化时,将变量本身传递给执行环境的调用者,调用者又在执行调用(DO_FCALL_BY_NAME)时将变量传递给EG(This),当执行这个方法的op_array时,初始化当前作用域的环境(zend_execute_data)时,会将EG(This)作为$this变量添加到活动符号表,后续方法中的$this变量的使用就会直接取符号表的变量。

永久链接:http://www.phprm.com/mxdx/fs1623.html

转载随意!带上文章地址吧。

标签:php 变量 $this

相关文章

发表留言