PHP語言中global和$GLOBALS[]的分析

網站建設原來覺得global和$GLOBALS除了寫法不同覺得,其餘都同樣,但是在實際應用中發現,2者的區別仍是很大的!
先看下面的例子:

PHP代碼
Java代碼   收藏代碼
  1. <?php    
  2. // 例子1    
  3. function test_global() {    
  4.   global $var1, $var2;    
  5.   $var2 =& $var1;    
  6. }    
  7. function test_globals() {    
  8.   $GLOBALS['var3'] =& $GLOBALS['var1'];    
  9. }    
  10. $var1 = 5;    
  11. $var2 = $var3 = ;    
  12. test_global();    
  13. print $var2 ."\n";    
  14. test_globals();    
  15. print $var3 ."\n";    
  16. ?>     


執行結果爲:
0
5

怎麼會這樣呢?不該該是2個5嗎?怎麼會出現1個0和1個5呢?

恩,咱們保留以上問題,深刻分析$GLOBALS和global的原理!

咱們都知道變量實際上是相應物理內存在代碼中的"代號",假設咱們上面聲明的3個變量分配的內存以下圖表示:

引用php手冊的$GLOBALS的解釋:

Global 變量:$GLOBALS
注意: $GLOBALS 在 PHP 3.0.0 及之後版本中適用。

由全部已定義全局變量組成的數組。變量名就是該數組的索引。

這是一個「superglobal」,或者能夠描述爲自動全局變量。
也就是說上面代碼中的$var1和$GLOBALS['var1']是指的同一變量,而不是2個不一樣的變量!

下面來分析global到底作了什麼?

咱們都知道php中的函數所產生的變量都是函數的私有變量,那麼global關鍵字產生的變量也確定逃不出這個規則,爲何這麼說呢,看下面的代碼:

PHP代碼
Java代碼   收藏代碼
  1. <?php    
  2. // 例子2    
  3. function test() {    
  4.   global $a;    
  5.    unset($a);    
  6. }    
  7.     
  8. $a = 1;    
  9. test();    
  10. print $a;    
  11. ?>      

複製代碼
執行結果爲:
1
爲何會輸出1呢?不是已經把$a給unset了嗎?unset失靈了?php的bug?

都不是,其實unset起做用了,是把test函數中的$a給unset掉了,能夠在函數後面加入
print $a;
複製代碼
來測試!也就是說global產生了test函數外部$a的別名變量「$a」,爲了和外面的$a區別,我把它成爲--test->$a,那麼例子1也這麼命名的話,可得出下面的圖:
[沒有圖,謝謝,忽悠你的]



接着回到上面的例子1,看test_global中的這一代碼「$var2 =& $var1;」,上面是一個引用賦值運算,也就是$var2將指向var1所指向的物理內存地址,因此例子1執行過test_global函數之後,變量的變化由下圖能夠看出:
[沒有圖,謝謝,忽悠你的]
而test_globals執行過之後,看變量的變化:

此時,看圖,就能理解爲何例子1執行完之後,$var2是0,而$var3是5了!

因此咱們得出一個結論,在函數中global和$GLOBALS[]的區別在於:

global在函數產生一個指向函數外部變量的別名變量,而不是真正的函數外部變量,一但改變了別名變量的指向地址,就會發生一些意料不到狀況,例如例子1.

網站建設$GLOBALS[]確確實實調用是外部的變量,函數內外會始終保持一致!(fblww-0227)
相關文章
相關標籤/搜索