程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 詳解類的靜態成員變量

詳解類的靜態成員變量

編輯:關於PHP編程

首先說下靜態變量和全局變量的區別,全局變量可以被所有函數訪問,如果多個獨立的函數使用了同名的變量,就會導致沖突,在只有一個函數需要訪問某個變量時,我們應該優先使用靜態變量,而不是全局變量

類中的靜態成員,它屬於整個類而不是屬於類的某個實例,靜態成員只保留一個變量值,而這個變量值對所有的實例都是有效的,所有的實例共享這個成員。

$this表示類的當前實例,Self::表示的是類本身 在類之外的代碼不能使用這個操作符,而且它也不能識別自己在繼承樹層次結構中的位置。也就是說在擴展類中使用self作用域時,self可以調用基類中聲明的方法,但他調用的總是已經在擴展類中重寫的方法。基類方法被重寫,但是如果要調用基類的方法,需要用到parent關鍵字。

         靜態成員也可以只屬於父類,父子類中都定義了某個成員,需要使用parent來訪問父類中的靜態成員。這種情況下父子類中保存的靜態成員值不同。

         使用靜態方式調用類中的方法,可以省略實例化類的代碼,並且還會更高效(省去實例化類時需要消耗的一小部分資源)

 


詞法語法分析流程

1 在文件Zend/zend_compile.c裡,詞法分析之後加上兩行代碼,用來打印出具體的詞法分析出來的分詞

   retval = lex_scan(&zendlval->u.constant TSRMLS_CC); //原先的詞法分析腳本

   if(zendlval->u.constant.value.lval && zendlval->u.constant.value.lval< 10000)

       printf("word: %ld\n", zendlval->u.constant.value.lval);

   else if(zendlval->u.constant.value.str.val)

       printf("word: %s\n", zendlval->u.constant.value.str.val);

2在詞法分析zend_language_scanner.c中打印出詞法鏈接的case條件,方便後續跟蹤

         printf("word-line:%d\n", yy_act);

   switch ( yy_act )

3 在語法分析zend_language_parser.c中打印出語法鏈接的case條件,方便後續跟蹤

         YY_REDUCE_PRINT(yyn);

printf("grammar-line: %d\n", yyn);

        switch(yyn)

4 構造包含static的類文件

 <?php

   class classname{

       public static $valname = 'test';

public $val = 'test1';

       function functionname(){

           echo self::$valname;

       }

   }

 

   $obj = new classname();

   echo $obj->functionname();

 

5 重要片段分析

word: classname

grammar-line: 93

grammar-line: 86    

走了zend_do_begin_class_declaration

初始化類的信息

並且把類注冊進入了CG(class_table)

將當前類設置為CG(active_class_entry)

最後取出了下個操作碼進行了設置

grammar-line: 98

grammar-line: 168

 

public

grammar-line: 183

grammar-line: 181

 

word: static

grammar-line: 186           

Z_LVAL((yyval).u.constant)= ZEND_ACC_STATIC;

grammar-line: 182

         走了這個函數zend_do_verify_access_types

         做了檢測,static不能用來限制abstract類的成員變量等

 

word: valname

grammar-line: 177

grammar-line: 169

 

word: test

grammar-line: 303

grammar-line: 309

grammar-line: 192

         調用了zend_do_declare_property函數

                   通過CG(active_class_entry)檢測,接口不能添加成員變量

                   變量不能是abstact和final

                   檢查是否進行了重復定義

                   調用zend_declare_property_ex

                   通過access_type& ZEND_ACC_STATIC這個判斷出來是否為靜態變量

                            如果是靜態變量則target_symbol_table= &ce->default_static_members;

                            如果不是則target_symbol_table= &ce->default_properties;

                   最後zend_hash_update更新屬性字段

 

6 結論

類的普通變量和成員變量都存儲在類結構的屬性裡面,僅是存儲在的目標hash表不同

 摘自 xiaoq3406的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved