首頁  >  文章  >  後端開發  >  php中global和$GLOBALS[]的實例詳解

php中global和$GLOBALS[]的實例詳解

零下一度
零下一度原創
2017-06-29 13:59:181223瀏覽

PHP 的全域變數和C 語言有一點點不同,在C 語言中,全域變數在函數中自動生效,除非被局部變數覆蓋

這可能會引起一些問題,有些人可能漫不經心的改變一個全域變數。 PHP 中全域變數在函數中使用時必須申明為全域(注意,Global這個關鍵字在函數中定義才有用)。 
1:Global的作用是定義全域變數,但是這個全域變數不是應用於整個網站,而是應用於目前頁面,包括include或require的所有檔案。

<?PHP 
$a=123; 
function aa() 
{


Global $a; //如果不把$a定義為global變數,函數體內是不能存取函數體外部的$a的,但是可以定義一個相同的名字$a,此時這個變數是局部變量,等同於C語言的局部變量,只能在函數體內部使用。

echo $a; 
} 
aa(); 
?>


總結:在函數體內定義的global變數,函數體外可以使用,在函數體外定義的global變數不能在函數體內使用, 

$global $a; 
$a=123; 
function f() 
{ 
echo $a; //错误, 
}


#//再看看下面一個例子 

function f() 
{ 
global $a; 
$a=123; 
} 
f();


echo $a; //正確,可以使用 


2:global問題解析: 
question:我在config.inc.php中定義了一些變數($a),在別的檔案中函數外部include("config.inc.php"),函數內部需要使用這些變數$a,如果沒有聲明的話,echo $a是印不出來任何東西的。因此聲明global $a,但是有很多函數和很多變量,總不能不斷重複的這樣聲明吧?有什麼好的解決辦法,請指著一點。
answer1:先在config.inc.php裡定義常數:define(常數名,常數值) 
再在其他需要用到的地方require 'config.inc.php', 
#然後就能在這個文件裡直接使用這個常數了。 
answer2:我也有辦法,就是定義數組,如$x[a],$x,那樣就只要宣告global $x一個了。 
answer3:我試了你的這個方法,不行啊。 
answer4:改變你的php.ini檔。 
3.一些Global和$GLOBALS 陣列的範例 

範例:使用 global 

<?PHP 
$w3sky = 1; 
$w3sky2 = 2; 
function Sum() 
{ 
global $w3sky, $w3sky2;$w3sky2 = $w3sky + $w3sky2; 
}Sum(); 
echo $w3sky2; 
?>


以上腳本的輸出將是「3」。在函數中申明了全域變數 $w3sky 和 ​​$w3sky2,任何變數的所有引用變數都會指向到全域變數。對於函數能夠申明的全域變數的最大個數,PHP 沒有限制。 
在全域範圍內存取變數的第二個方法,是用特殊的 PHP 自訂 $GLOBALS 陣列。前面的例子可以寫成: 
範例 使用 $GLOBALS 取代 global 

<?PHP 
$w3sky = 1; 
$w3sky2 = 2;function Sum() 
{ 
$GLOBALS[&#39;w3sky&#39;] = $GLOBALS[&#39;w3sky&#39;] + $GLOBALS[&#39;w3sky2&#39;]; 
}Sum(); 
echo $w3sky2; 
?>


在 $GLOBALS 陣列中,每一個變數為一個元素,鍵名對應變數名,值對應變數的內容。 $GLOBALS 之所以在全域範圍內存在,是因為 $GLOBALS 是一個超全域變數。以下範例顯示了超全域​​變數的用處: 
範例示範超全域變數和作用域的範例 

<?PHP function test_global() { // 大多数的预定义变量并不 "super",它们需要用 &#39;global&#39; 关键字来使它们在函数的本地区域中有效。 global $HTTP_POST_VARS;echo $HTTP_POST_VARS[&#39;name&#39;];// Superglobals 在任何范围内都有效,它们并不需要 &#39;global&#39; 声明。Superglobals 是在 PHP 4.1.0 引入的。 echo $_POST[&#39;name&#39;]; } ?>

global 也就是說是在一個檔案裡只要你宣告為global $db 那麼在宣告的下面你就可以引用這個$db了。
4.原來以為global和$GLOBALS除了寫法不一樣以為,其他都一樣,可是在實際應用中發現,2者的區別還是很大的! 
先看下面的例子: 

<?php 
// 例子1 
function test_global() { 
global $var1, $var2; 
$var2 =& $var1; 
} 
function test_globals() { 
$GLOBALS[&#39;var3&#39;] =& $GLOBALS[&#39;var1&#39;]; 
} 
$var1 = 5; 
$var2 = $var3 = 0; 
test_global(); 
print $var2 ."\n"; 
test_globals(); 
print $var3 ."\n"; 
?>


複製程式碼 
執行結果為: 


怎麼會這樣呢?不應該是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 // 例子2 function test() { global $a; unset($a); } $a = 1; test(); print $a; ?>

执行结果为: 

为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug? 
都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数后面加入 
print $a; 
复制代码 
来测试!也就是说global产生了test函数外部$a的别名变量“$a”,为了和外面的$a区别,我把它成为--test->$a,那么例子1也这么命名的话,可得出下面的图: 
而test_globals执行过以后,看变量的变化: 
此时,看图,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了! 
所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于: 
global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况(为什么会打印结果为2呢?其实就是因为$var1的引用指向了$var2的引用地址。导致实质的值没有改变。这时候只是指向$var1的指针指向了$var2的指针,只是指针指向变了一下,但是实质上根本就没有改变$var2的值,因此$var2的值仍旧不会变化),例如例子1. 
$GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致! 
注:(接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化只在函数的局部产生效应,在函数外部$var2的指向物理内存地址并没有变化,还是它自己.(重点) 
接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化由下图可以看出) 

以上是php中global和$GLOBALS[]的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn