淺談php中global與$GLOBALS[' ']的區別
一直以為在php中global和$GLOBALS[’ ‘]沒有什麼差別,今天查了一下,發現兩者的有很大的差別.特作出以下總結:
global $var : 是指向全域性變數$var的一個引用;
$GLOBALS[“var”] : 是全域性變數 $var本身, 即等價於$var.
下面舉幾個例子:
例1:
<?php
$var1 = 1;
$var2 = 2;
function test() {
$GLOBALS['var2'] = &$GLOBALS['var1'];
}
test();
echo $var2 ;//輸出1
?>
test() 函式中$GLOBALS[‘var2’] 相當於全域性變數$var1,
$GLOBALS[‘var2’] = $GLOBALS[‘var1’] 作用是將$var2變為$var1的引用,即$var2是$var1的別名,兩者指向同一個記憶體空間,所以\$var2的值變為1。
例2:
<?php
$var1 = 1;
$var2 = 2;
function test(){
global $var1, $var2;
$var2 = &$var1;
echo $var2;
$var2 = 'hello...';
}
test(); // 輸出 1
echo $var2; // 輸出 2
echo $var1; // 輸出 hello...
?>
在test函式中 $var1和$var2分別是全域性變數$var1和$var2的引用(即別名)
$var2 = &$var1; //test函式中的$var2(區域性變數)的值更改為該函式內的$var1的引用
此時test函式中$var2的值等於該函式中$var1的值,也等於全域性變數中$var1的值,三者指向同一塊記憶體空間,當test函式中的$var2的值發生變化時,另外兩個(test函式中的$
例3.
<?php
$var1 = 1;
function test(){
unset($GLOBALS['var1']);
}
test();
echo $var1;
?>
正如上面所講到的,$GLOBALS[‘var1’] 與 全域性變數中的$var1是等價的,unset($GLOBALS[‘var1’] );等價於將全域性變數$var1銷燬,所以列印空
補充:
php中unset()函式是用來銷燬變數的,在很多時候,它只是將變數銷燬,但記憶體裡面的值並沒有銷燬(即unset()函式指數切斷變數與記憶體之間的關係,將變數名銷燬,記憶體裡面的值並沒有銷燬,記憶體也沒有釋放),需要注意的是:
1. 該函式只在變數所佔的記憶體超過256個位元組的時候,才會將記憶體釋放。
2. 只有在所有指向該變數所指向的記憶體的變數(如該變數的所有引用)都被銷燬,地址才會被釋放。
例4.
<?php
$var1 = 1;
function test(){
global $var1;
unset($var1);
}
test();
echo $var1; //結果為列印1
?>
在這段程式碼裡,test()函式中使用global定義的變數其實只是一個指向全域性變數$var的引用,在test()函式中銷燬該變數相當於銷燬了全域性變數的一個引用(一塊記憶體,有兩個名字,刪去其中的一個名字,對另一個名字和該記憶體的值並不會有影響),所以,當在列印全域性變數$var時,結果仍是1。該段程式碼與下面的程式碼所進行的操作是類似的:
<?php
$var = 1;
$var1 = &$var;
unset($var1);
echo $var;
?>
再看一個在函式內部引用全域性變數的例子:
<?php
$var1 = "我是變數var1的值";
$var2 = "我是變數var2的值";
function global_references($use_globals) {
global $var1, $var2;
if (!$use_globals) {
$var2 = &$var1;
echo $var1;
echo $var2;
echo "<br />";
} else {
$GLOBALS["var2"] = &$var1;
echo $var1;
echo $var2;
echo "<br />";
}
}
global_references(false);//1.列印:我是變數var1的值我是變數var1的值
echo $var1;
echo $var2;
echo "<br />"; //2.列印:我是變數var1的值我是變數var2的值
global_references(true); //3.列印:我是變數var1的值我是變數var2的值
echo $var1;
echo $var2;
echo "<br />"; //4.列印:我是變數var1的值我是變數var1的值
?>
- 因為引數為false,所以執行if裡面的語句,將global_references()函式內宣告的原本為全域性變數var2引用的var2的值變為var1的引用,所以global_references()函式內列印的兩個變數都是全域性變數var1的引用。
- 1執行的語句並沒有對全域性變數的值產生影響,所以列印的還是程式開始宣告的值。
- 因為引數為true,所以執行else裡面的語句,將全域性變數var1的值變為全域性變數var1的引用(global_references()函式內宣告的var1)的引用,這並沒有改變global_references()中宣告的var2的值(仍為原來記憶體的引用)。
- 經過3之後,全域性變數var2已經成為全域性變數var1的引用了,所以此時兩個全域性變數的值相同。
總結:
global $var : 是指向全域性變數$var的一個引用;
$GLOBALS[“var”] : 是全域性變數 $var本身, 即等價於$var.
前者若是在函式內部宣告的變數,其作用域為該函式,即只在該函式內可見,這個變數是一個指向全域性變數的引用,銷燬該變數並不會對其所指向的全域性變數有影響。