1. 程式人生 > >淺談php中global與$GLOBALS[' ']的區別

淺談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函式中的$

var1和全域性變數中的$var1)的值也隨之發生變化。

例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的值
?>
  1. 因為引數為false,所以執行if裡面的語句,將global_references()函式內宣告的原本為全域性變數var2引用的var2的值變為var1的引用,所以global_references()函式內列印的兩個變數都是全域性變數var1的引用。
  2. 1執行的語句並沒有對全域性變數的值產生影響,所以列印的還是程式開始宣告的值。
  3. 因為引數為true,所以執行else裡面的語句,將全域性變數var1的值變為全域性變數var1的引用(global_references()函式內宣告的var1)的引用,這並沒有改變global_references()中宣告的var2的值(仍為原來記憶體的引用)。
  4. 經過3之後,全域性變數var2已經成為全域性變數var1的引用了,所以此時兩個全域性變數的值相同。

總結:
global $var : 是指向全域性變數$var的一個引用;
$GLOBALS[“var”] : 是全域性變數 $var本身, 即等價於$var.
前者若是在函式內部宣告的變數,其作用域為該函式,即只在該函式內可見,這個變數是一個指向全域性變數的引用,銷燬該變數並不會對其所指向的全域性變數有影響。