国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

PHP $this變量一些理解

2024-09-04 11:43:36
字體:
供稿:網(wǎng)友

在PHP的詞法分析時(shí),$this變量是符合其規(guī)則的,在語法解析生成中間代碼時(shí),PHP內(nèi)核會根據(jù)變量類型在生成賦值的中間代碼時(shí)判斷是否為$this變量,如果是則報(bào)錯(cuò)。這里為什么要報(bào)錯(cuò)呢?因?yàn)閠his作為一個(gè)特殊的變量,在對象的成員方法等調(diào)用初始化時(shí)會將this變量添加到活動符號表。

在類的成員方法里面,可以用 ->(對象運(yùn)算符):$this->property(其中 property 是該屬性名)這種方式來訪問非靜態(tài)屬性。

當(dāng)一個(gè)方法在類定義內(nèi)部被調(diào)用時(shí),有一個(gè)可用的偽變量 $this。$this 是一個(gè)到主叫對象的引用(通常是該方法所從屬的對象,但如果是從第二個(gè)對象靜態(tài)調(diào)用時(shí)也可能是另一個(gè)對象)。

在詞法分析、語法分析并生成中間代碼時(shí),$this作為一個(gè)特殊的變量存在,特別是在生成中間代碼時(shí),代碼中充斥著對于this的特殊處理。這些都是為后面的運(yùn)行做準(zhǔn)備,如識別標(biāo)記出某處使用this變量,在存儲opcode的zend_op_array結(jié)構(gòu)體中專門有一個(gè)變量this_var標(biāo)識是否有this變量。一個(gè)函數(shù)或一個(gè)類方法都會生成一個(gè)新的zend_op_array,在生成中間代碼時(shí),判斷當(dāng)前變量是否為this變量。

this變量在執(zhí)行過程中會有兩種存在狀態(tài),一種是全局傳遞的狀態(tài),存儲在EG(This),一種是當(dāng)前作用域狀態(tài),以this變量存儲在EG(active_symbol_table)(當(dāng)前執(zhí)行環(huán)境的活動符號表)。

在我們執(zhí)行一個(gè) op_array 時(shí),比如一個(gè)對象的方法,PHP內(nèi)核會給這個(gè) op_array 生成一個(gè) zendexecutedata ,在生成初始化時(shí),EG(This) 會添加到EG(active_symbol_table) 。

在方法調(diào)用過程中,如果有用到this變量,則會直接取EG(active_symbol_table)的值。

那么一個(gè)對象中的EG(This)在哪里初始化呢?

就EG(This)變量本身來說,在我們初始化PHP的執(zhí)行環(huán)境時(shí),它和其它全局變量(如EG(scope)等)一樣都會被初始化為NULL。

對于一個(gè)對象來說,當(dāng)我們創(chuàng)建了一個(gè)對象,調(diào)用時(shí),PHP內(nèi)核會將當(dāng)前獲得的對象直接賦值給EG(This),而這個(gè)當(dāng)前獲得的對象是在通過new操作生成對象時(shí)創(chuàng)建的對象本身。

如下這個(gè)簡單示例:

  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,經(jīng)過了賦值(ASSIGN)后,在方法初始化時(shí),將變量本身傳遞給執(zhí)行環(huán)境的調(diào)用者,調(diào)用者又在執(zhí)行調(diào)用(DO_FCALL_BY_NAME)時(shí)將變量傳遞給EG(This),當(dāng)執(zhí)行這個(gè)方法的op_array時(shí),初始化當(dāng)前作用域的環(huán)境(zend_execute_data)時(shí),會將EG(This)作為$this變量添加到活動符號表,后續(xù)方法中的$this變量的使用就會直接取符號表的變量。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 高碑店市| 龙里县| 博白县| 大连市| 纳雍县| 项城市| 麦盖提县| 南京市| 枝江市| 昌宁县| 浦城县| 呈贡县| 元氏县| 藁城市| 会宁县| 比如县| 五家渠市| 县级市| 城口县| 石首市| 廊坊市| 甘谷县| 南陵县| 平利县| 德庆县| 乌兰浩特市| 格尔木市| 霍山县| 和平县| 嵩明县| 定边县| 蒙自县| 读书| 宁蒗| 昌平区| 延川县| 南城县| 静海县| 阿克陶县| 神农架林区| 彭山县|