PHP變數的記憶體布局 實現方法以及作用域

2021-06-20 22:10:01 字數 2855 閱讀 5505

前段時間用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布局的實現方法

我們目前已經學會了四個控制項,也編出了幾個視窗例項,它們都有乙個共同的特點,就是醜,主要原因是沒有進行合理地布局。此前的布局方式簡單粗暴,即明確規定每個控制項的大小和位置,從而使之固定。這種布局方式可稱之為絕對定位布局,缺點是控制項尺寸固定,並不會隨著視窗的放縮而同步變化。而且所有的控制項都處於同一...