在php中沒有對常規變數的宣告操作,如果要使用乙個變數,直接進行賦值操作即可,因為php在賦值操作的同時已經進行宣告操作,那麼php是怎樣在賦值前進行宣告的呢?
在博文《深入理解php原理之變數賦值》中其實已經提到過變數的宣告,但是講述的不夠透徹,下面主要通過詞法分析、語法分析和獲取左值和右值的過程,來講述變數宣告的原理。
下面是乙個簡單的變數賦值操作:
$a = 'hello world';
在賦值前,我們先看看變數a是怎樣儲存的,之前我們在《深入理解php原理之變數賦值》中講過,是這麼描述變數a的「因為變數名a其實有乙個指標ptr_a,每次初始化乙個變數時,系統會先開闢一塊記憶體,將變數的值保持在zval中,然後將變數a和對應的指標ptr_a保持在數值中,同時讓ptr_a指向zval的首位址」,其實在執行的過程中,變數名及指標主要儲存_zend_executor_globals的符號表中,_zend_executor_globals的結構如下:
struct _zend_executor_globals
其中active_symbol_table和symbol_table中儲存不同型別變數的變數名,opline_ptr是指向變數值的指標,變數a就儲存在該陣列中。
知道了變數的儲存方法,我們還是回到之前的賦值語句,該語句經過詞法分析和語法分析後,大致會解析為以下的條件語句:
fetch_w
local
!0, 'a'
assign
!0, 'hello+world'
第一行是將變數a儲存到臨時變數!0(前面的感嘆號,表示資料放在快取),第二行是進行賦值操作,在賦值前需要獲取左值和右值,**如下:
zval *value = &opline->op2.u.constant;
zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1,ex(ts), bp_var_w
tsrmls_cc);
由於右值為乙個數值,我們可以理解為乙個常量,則直接取運算元儲存的constant欄位,左值是通過 _get_zval_ptr_ptr_cv函式獲取zval值,**如下:
static zend_always_inline zval **_get_zval_ptr_ptr_cv(const znode *node, const
temp_variable *ts, int type tsrmls_dc)
return
*ptr;
}// 函式中的cv_of巨集定義
#define cv_of(i) (eg(current_execute_data)->cvs[i]
)
該函式中先呼叫cv_of(node->u.var),cv_of是個巨集,展開後其實呼叫的是cvs,那什麼是cvs呢?它其實就是個快取,以陣列的形式快取變數所在hashtable的值,獲取變數的值前,先從快取中取,用於提高效率(是不是可以和之前提到的「fetch_w local !0, 『a』」對應起來呢,!0表示資料在快取)。如果在快取中沒有獲取到,呼叫方法_get_zval_cv_lookup(),該方法通過eg(active_symbol_table)表查詢變數。
上面是在變數賦值前進行的一些操作,我把他們定義為「變數的宣告」,具體賦值操作,可以參考我之前的博文《深入理解php原理之變數賦值》,裡面講的非常詳細。
可能大家感覺有點暈,我總結一下,當變數進行賦值時,如$a=1,先將變數a放在快取中,這個變數包含變數名a和指標(此時的指標可以理解為空指標,因為還沒有給它賦值),然後是獲取左值和右值,右值的獲取很easy,左值的獲取分2步,即先到快取中找,如果沒有,就到雜湊表中找,最後就是賦值操作,結束!
參考:
深入理解PHP原理之變數賦值
在前面的文章 深入理解php原理之變數結構 中我已經介紹了php變數的內部結構,下面我將會對變數賦值過程中,php內部對資料處理的原理進行闡述,不過在講述該原理前,需要先了解一下變數名和它的值是如何關聯起來的,這個對變數賦值內部原理的理解非常重要,例如 a 1 這個例子看起來非常簡單,但是你知道 變...
深入理解PHP原理之變數作用域
php變數的內部表示是如何和使用者指令碼中的變數聯絡起來的呢?也就是說,如果我在指令碼中寫下 var laruence echo var ze是如何把我的變數var和內部結構zval聯絡起來的呢?深入理解php原理之變數中講過,php內部都是使用zval來表示變數的,但是對於上面的指令碼,我們的變數...
深入淺出理解PHP原理之變數賦值
php的變數賦值 這個標題估計很多人會不屑一顧,變數賦值?excuse me?我們學開發的第一課就會了好不好。但是,就是這樣基礎的東西,反而會讓很多人矇圈,比如,值和引用的關係。今天,我們就來具體講講。首先,定義變數和賦值這個不用多說了吧 a 1 b 2 c 4,5,6 d new stdclass...