深入理解PHP原理之變數作用域

2021-08-26 10:47:59 字數 1324 閱讀 2114

php變數的內部表示是如何和使用者指令碼中的變數聯絡起來的呢?也就是說,如果我在指令碼中寫下:

<?php

$var="laruence";

echo$var;

?>

ze是如何把我的變數var和內部結構zval聯絡起來的呢?

深入理解php原理之變數中講過,php內部都是使用zval來表示變數的,但是對於上面的指令碼,我們的變數是有名字的, var。而zval中並沒有相應的字段來體現變數名。

如果你想到了php內部一定有乙個機制,來實現變數名到zval的對映。那麼你真的是很聰明,;)

在php中,所有的變數都會儲存在乙個陣列中(確切的說是hash table), 並且,php也是通過不同的陣列來實現變數的作用域的。

當你建立乙個變數的時候,php會為這個變數分配乙個zval,填入相應的變數值,然後將這個變數的名字,和指向這個zval的指標填入乙個陣列中。然後,當你獲取這個變數的時候,php會通過查詢這個陣列,獲得對應的zval。

檢視_zend_executor_globals結構(這個結構在php的執行器儲存一些執行相關的上下文資訊)

struct

_zend_executor_globals

其中,全域性符號表,儲存了在頂層作用域(就是不在任何函式,物件內)的變數。每當呼叫乙個函式(物件的方法)的時候,就會為這個函式建立乙個活動符號表,所有在這個函式內定義的變數,都會儲存在這個活動符號表中。

對,這就是php的變數作用域的實現方式! 舉個列子:

<?php

$var="i am in the global symbol table";

function

sample

($para)

sample

($var)

;echo$var;

?>

在函式sample外面的變數$var,它會被填入全域性符號表中,與他對應的有乙個zval指標,這個zval儲存了乙個字串」i am in the global symbol table」.

函式內的$var, 它會被填入屬於函式sample的活動符號表中,一樣的,與他對應的zval中,儲存著字串」i am in the active symbol table「.

比較特殊的,就是函式sample的引數$para了,這個$para是儲存在sample的活動符號表的,但是與他對應的zval指標,會指向乙個儲存乙份全域性變數$var的copy的zval(嚴格來講不是copy,是引用,這個涉及到變數的copy on write機制,我會在以後介紹)。

我們都知道php對於簡單變數是傳值呼叫的,但是,我要告訴你的是,php並不是簡單的通過複製乙個zval來實現傳值的,呵呵,留個懸念,等我下回分解.

深入理解PHP原理之變數賦值

在前面的文章 深入理解php原理之變數結構 中我已經介紹了php變數的內部結構,下面我將會對變數賦值過程中,php內部對資料處理的原理進行闡述,不過在講述該原理前,需要先了解一下變數名和它的值是如何關聯起來的,這個對變數賦值內部原理的理解非常重要,例如 a 1 這個例子看起來非常簡單,但是你知道 變...

深入理解PHP原理之變數宣告

在php中沒有對常規變數的宣告操作,如果要使用乙個變數,直接進行賦值操作即可,因為php在賦值操作的同時已經進行宣告操作,那麼php是怎樣在賦值前進行宣告的呢?在博文 深入理解php原理之變數賦值 中其實已經提到過變數的宣告,但是講述的不夠透徹,下面主要通過詞法分析 語法分析和獲取左值和右值的過程,...

深入理解變數 作用域 記憶體

變數這個概念其實說簡單也簡單,說複雜也複雜。特別是再記憶體的角度來理解 1 我們暫且不管堆記憶體和棧記憶體是什麼?我們把房間比作堆記憶體 房間號比作棧記憶體 2 定義 引用型別是堆記憶體中物件 基本型別是棧記憶體簡單資料段 3 這句話如何理解?4 var home 12 這代表房間的門牌號是12 v...