淺談php變數的實現-PHP
php - @amazeUI - 2017-02-04 08:34:48
1.php是如何執行的
php作為一個指令碼語言,但不是靠直譯器來解釋語言。php程式碼首先經過zend編譯器,將php程式碼編譯成opcode,再由虛擬的一個zend虛擬機器來執行這段opcode,這種執行模式與java有些類似,java是先編譯成 .class檔案再由虛擬機器來執行,java本身這個語言不是跨平臺的,而是這個虛擬機器是跨平臺的,java程式執行完畢後,class檔案會儲存下來,下次執行直接執行,與php不同,php轉成的opcode當程式執行結束後opcode會被清除不會被保留,下次再執行會再次生成opcode。
2.php是c語言實現的,而c語言是強型別語言,php是弱型別語言,這是如何實現的zend.h
php無需宣告一個變數的型別,就可以賦值,底層是如何描述這個變數的呢,php的變數在底層是以一個基本的結構體描述一個變數的。
這個是php變數在記憶體中的儲存結構(在php原始碼Zend/zend.h裡)
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */->這個是一個聯合體,儲存著這個變數的值和其他資訊
zend_uint refcount__gc;->這裡最好理解成這個結構體一共有幾個變數在使用
zend_uchar type; /* active type */->這裡儲存這個值的變數的基礎型別(一共八種)
zend_uchar is_ref__gc;->這裡表示這個變數是否為引用的值的(0為否,1為是)
};
這個就是上面所說的聯合體
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;->一個字串型別,裡面包含了一個字串長度
HashTable *ht; /* hash table value */->這帶包一個雜湊表指標
zend_object_value obj;->這代表物件
} zvalue_value;
如果仔細觀察會發現這個聯合只有五種資料結構,並沒有php的八種資料結構(結構體裡也是八種),和php的八種資料結構差了三個,null,bool,resource。
可以確定的是所有變數都是由這個結構體來實現的,null在底層可以沒有這個型別,在結構體裡的type直接設定為IS_NULL,zvalue_value就可以不必設定了,布林型別的在type裡為is_bool,在聯合體中直接設定為0/1就可以了,資源型別在type裡設定為資源,然後在value裡的表示為一個介面的編號。
那$a=1;這一個動作發生了什麼呢,執行到這一句,在記憶體中會多出一個結構體和一個聯合體,在全域性符號表(也就是雜湊表)中會多出一條記錄,記錄這個變數的名字a,和這個變數的值的記憶體地址,也就是那個結構體的記憶體地址。
那$b=$a;這一傳值賦值發生了什麼。執行到這一句,並沒有再多出一個結構體,只是全域性符號表裡再多出一條記錄也是指向$a這個結構體的,這個結構體的refcount__gc變為2,表示有兩個變數名指向了這個結構體。如果隨便再給$a或者$b賦一個其他的值,結構體會分裂成兩個,比如說$a=2;首先會看這個結構體的is_ref__gc是否等於0,如果是,則這個時候會多出一個結構體,雜湊表裡的$a的地址也會指向值為2的結構體。這種特性叫做寫時複製(簡寫為cow,copy on write),很多種語言都有這種特性,就是為了省記憶體。如果不是傳值賦值而是引用賦值的話,is_ref_gc等於1,公用一個結構體。
鳥哥的部落格裡有更深入的解釋
相關文章
- 淺談PHP-FPM引數PHP
- 淺談PHP fastcgi和php-fpmPHPAST
- 淺談php 取餘PHP
- 【深入 PHP】PHP7 的基本變數PHP變數
- 淺談PHP弱型別安全PHP型別
- 淺談php count()函式方法PHP函式
- 淺談 PHP 中異常類的使用PHP
- 2020024 - PHP 變數PHP變數
- 潛藏在PHP安全的邊緣——淺談PHP反序列化漏洞PHP
- 淺談變數型別之外的變數命名變數型別
- PHP變數型別PHP變數型別
- 淺談PHP物件導向程式設計PHP物件程式設計
- 淺談 class 私有變數變數
- 淺談class私有變數變數
- 自學PHP筆記(四) PHP變數和常量PHP筆記變數
- 自學PHP筆記(四) PHP常量和變數PHP筆記變數
- [PHP] 演算法-陣列重複數字統計的PHP實現PHP演算法陣列
- 每天一個 PHP 語法-變數使用及內部實現PHP變數
- 私聊(PHP 實現)PHP
- MongoDB changeStream 的 PHP 實現MongoDBPHP
- PHP 超級全域性變數PHP變數
- PHP->GO 基礎-變數PHPGo變數
- PHP變數與常量學習PHP變數
- PHP中GET與POST變數PHP變數
- 淺談Java、PHP、C++程式設計的優缺點JavaPHPC++程式設計
- C 語言是怎樣實現儲存一個 PHP5 的變數?PHP變數
- PHP 函式可變數量的引數列表PHP函式變數
- 淺談Innodb的鎖實現
- 【深入 PHP】PHP7 陣列的底層實現PHP陣列
- 淺析如何通過PHP類的反射來實現依賴注入PHP反射依賴注入
- PHP 變數的四大作用域PHP變數
- php判斷變數是不是null的方法PHP變數Null
- 淺談 PHP 中的 Trait 使用方法,報錯如何解決PHPAI
- php底層原理之變數(一)PHP變數
- PHP變數覆蓋漏洞小結PHP變數
- PHP基本語法學習 [變數]PHP變數
- PHP超全域性變數$_SERVER分析PHP變數Server
- php底層原理之變數(二)PHP變數