前段時間用php開發了乙個qqgame的後台發布系統(覺得使用php開發一些組內的工具是非常方便的。後來就打算把php了解的深入一點,要知道,c/c++程式設計師總是喜歡**某語言底層的實現,難道是沒被各類記憶體問題虐夠?
想深入了解php的實現原理
主要內容包括:
php變數的記憶體布局,
php弱型別的實現原理,
php變數的型別和作用域等;
1.
php變數的記憶體布局
下圖是變數在記憶體中的布局:
1.
php若型別的實現原理
php是乙個弱型別、動態的指令碼語言。弱型別是說
php並不嚴格驗證變數型別,在申明變數的時候不需要顯示指明它儲存的資料的型別。
動態指令碼語言是說
php的語言結構在執行期是可變的,例如我們在執行期
require
乙個函式定義檔案,會導致語言的函式表動態的改變。
大家都知道
c/c++
是強型別語言,即
所有的變數在它被宣告到最終銷毀,都只能儲存一種型別的資料。
那php
是如何在
zend
引擎的基礎上實現弱型別的呢? 在
php中,所有的變數都是用乙個結構
_zval_struct
來儲存的,在
zend/zend.h
中可以看到
_zval_struct
的定義:
zvalue_value
是儲存資料的關鍵部分,是個
union體
,定義如下:
php根據_zval_struct
中的type
欄位來儲存乙個變數的真正型別,然後根據
type
來選擇如何獲取
zvalue_value
的值。其中,
type
支援的資料型別如下:
對於陣列和物件,
type
分別對應
is_array, is_object,
相對應的則分別取
_zval_struct.value.ht
和_zval_struct .value.obj;
在php
中,資源是個很特別的變數,任何不屬於
php內建的變數型別的變數,都會被看作成資源來進行儲存,比如,資料庫控制代碼,開啟的檔案控制代碼等等。
對於資源,
zend
引擎會去取
_zval_struct l.value.lval
,此時的
lval
是個整型的指示器,然後
php會再根據這個指示器在
php內建的乙個資源列表中查詢相對應的資源。
借用這樣的機制,
php就實現了弱型別,因為對於
zend
引擎來說,它所面對的永遠都是同一種型別,即
_zval_struct。
2.
php變數的型別、作用域
變數的作用域:變數所起作用的範圍;
大部分的
php
變數只有乙個單獨的範圍。這個單獨的範圍跨度同樣包含了
include
和require
引入的檔案。
例如:變數$a
將會在包含檔案
file2.inc.php
中生效,
列印出100;
區域性變數:
i.多數
php變數都是區域性變數,在其作用域外無法引用,並且超出其作用域時自動銷毀。
ii.在當前檔案主程式中定義的變數,其作用域限於當前檔案的主程式,不能在其他檔案或當前檔案的區域性函式中起作用。
iii.
在區域性函式中定義的變數僅限於當前函式,當前檔案中主程式、其他函式、其他檔案中無法引用。(這點和
c/c++
一致)
b)全域性變數:
i.php
的全域性變數和
c/c++
稍有不同 1.
c/c++語言
中,全域性變數在函式中自動生效,除非被區域性變數覆蓋。 2.
php中,在函式中使用全域性變數時必須使用
「global」
、$globals["
變數名稱
"]關鍵字申明為全域性,否則視為區域性變數。
ii.在php
程式執行時,系統會在記憶體中保留一塊全域性變數的區域。(這點和
c/c++
一致)
iii.
使用「global」
關鍵字來申明全域性資料的缺點:
全域性資料把**中原本單獨的**段都聯絡在一起了,這樣的後果就是如果改變其中某一部分**,可能就會導致其它部分出錯。
1.
**重用幾乎是不可能的
如果乙個函式依賴於全域性變數,那麼想在不同的環境中使用這個函式幾乎是不可能的。
另外乙個問題就是你不能提取出這個函式,然後在其他的**中使用。
2.
除錯並解決問題是非常困難的
跟蹤乙個全域性變數比跟蹤乙個非全域性變數困難的多。
3.
理解這些**將是非常難的事情
很難弄清楚乙個全域性變數是從**來,以及是用來做什麼的。
c)
靜態變數: i.
靜態變數僅在區域性函式域中存在,但當程式執行離開此作用域時,其值並不丟失。
ii.靜態作用域對遞迴函式很有用。
windows下變數的記憶體布局
今天除錯顏色值得時候,發現了乙個超出我認知常理的事情。請看如下 union testunion uint32 t rgba int main int intdata 1 24 2 16 3 8 4 testunion testunion testunion intdata std cout test...
C 記憶體布局 變數在堆疊的分配
1.變數的記憶體分布 const變數儲存在.rodata read only 區域 char p abcd p指向的是靜態文字區域.text rodata 和 text 被合併為乙個segment,由os保護起來,只可讀。register變數存放在.bss區域 區域性變數存放在棧空間,static變...
wxpython布局的實現方法
我們目前已經學會了四個控制項,也編出了幾個視窗例項,它們都有乙個共同的特點,就是醜,主要原因是沒有進行合理地布局。此前的布局方式簡單粗暴,即明確規定每個控制項的大小和位置,從而使之固定。這種布局方式可稱之為絕對定位布局,缺點是控制項尺寸固定,並不會隨著視窗的放縮而同步變化。而且所有的控制項都處於同一...