萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP $this變量一些理解

PHP $this變量一些理解

本文章晉級人各位同學介紹關於PHP $this變量一些理解,希望些文章對各位同學會有所幫助。


手冊上的一個有意思的小示例。
http://www.php.net/manual/zh/language.variables.basics.php

 代碼如下 復制代碼

 $this = 'text'; // error
 $name = 'this';
 $$name = 'text'; // sets $this to 'text'

 echo $$name;

在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操作生成對象時創建的對象本身。

如下這個簡單示例:

 代碼如下 復制代碼  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變量的使用就會直接取符號表的變量。

copyright © 萬盛學電腦網 all rights reserved