首页 > 语言 > PHP > 正文

PHP $this变量一些理解

2024-09-04 11:43:36
字体:
来源:转载
供稿:网友

在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操作生成对象时创建的对象本身。

如下这个简单示例:

  1. class Foo { 
  2.       public $var = 10; 
  3.  
  4.       function t() { 
  5.            echo $this->var;      
  6.       } 
  7.  
  8.       function t2() { 
  9.        echo 33; 
  10.   } 
  11.  } 
  12.  
  13.  $foo = new Foo(); 
  14.  $foo->t(); 

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

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表