首頁  >  文章  >  後端開發  >  關於PHP中global的問題

關於PHP中global的問題

WBOY
WBOY原創
2016-10-23 00:12:541459瀏覽

各位大神中午好,我在網路上看到了這麼一個知識點:
函數內部聲明的global變數可以被外部主程式存取

接著我運行了下面的程式碼,也驗證了上面的結論:

<code><?php 

function test_global() {
    global $vars;
    $vars='OK';  
}
 
test_global();  
echo $vars;      //OK
?>
</code>

依據上面的理論,我又寫瞭如下的程式碼:

<code><?php 
$var1 = 1; 
function test(){ 
    global $var1;                       
    unset($GLOBALS['var1']);           
    echo $var1;
} 
test(); 
echo $var1;
?>
</code>

test函數內的global $var1是外部變數$var1的引用,unset($GLOBALS['var1']);使外部$var1斷開與記憶體的關聯(銷毀了變數$var1)

那麼問題來了
依照問題開頭的理論,即使外部的$var1被unset了,但是函數外部依然可以存取到函數內部的$var1啊? (函數內的$var1也是global的啊!),但是為什麼最後echo $var1會報錯呢?
還請大神賜教,謝謝了!

另外我還有一個問題,希望大神可以幫我看看
https://segmentfault.com/q/10...

回覆內容:

各位大神中午好,我在網路上看到了這麼一個知識點:
函數內部聲明的global變數可以被外部主程式存取

接著我運行了下面的程式碼,也驗證了上面的結論:

<code><?php 

function test_global() {
    global $vars;
    $vars='OK';  
}
 
test_global();  
echo $vars;      //OK
?>
</code>

依據上面的理論,我又寫瞭如下的程式碼:

<code><?php 
$var1 = 1; 
function test(){ 
    global $var1;                       
    unset($GLOBALS['var1']);           
    echo $var1;
} 
test(); 
echo $var1;
?>
</code>

test函數內的global $var1是外部變數$var1的引用,unset($GLOBALS['var1']);使外部$var1斷開與記憶體的關聯(銷毀了變數$var1)

那麼問題來了
依照問題開頭的理論,即使外部的$var1被unset了,但是函數外部依然可以存取到函數內部的$var1啊? (函數內的$var1也是global的啊!),但是為什麼最後echo $var1會報錯呢?
還請大神賜教,謝謝了!

另外我還有一個問題,希望大神可以幫我看看
https://segmentfault.com/q/10...

可以這麼理解:global $var1;等於$var1=&$GLOBALS['var1'];

<code><?php 
$var1 = 1; 
function test(){ 
    global $var1;                       
    unset($GLOBALS['var1']);           
    echo $var1;
} 
test(); 
echo $var1;
?></code>

可以對比上下兩段運行結果

<code><?php 
$var1 = 1; 
function test(){ 
    global $var1;                       
    unset($var1);
    echo $var1;
} 
test(); 
echo $var1;
?></code>

我也來補充一段吧

<code><?php
//#1全局的时候$GLOBALS['var']就是$var。
$var=999;
unset($GLOBALS['var']);
var_dump($var); //报错 NULL


//#2在函数内部,$GLOBALS['var']就是外部全局的$var
$var=999;
function test(){
    unset($GLOBALS['var']);
}
test();
var_dump($GLOBALS['var']); //报错 NULL
var_dump($var); //报错 NULL


//#3没有全局$var的时候,函数内部执行global $var;会创建一个空值的内部$var和一个空值的外部$var,在链接起来。
function test2(){
    global $var;
    var_dump($var); //NULL
    var_dump($GLOBALS['var']); //NULL
    $var = 999;
}
test2();
var_dump($var); //999
var_dump($GLOBALS['var']); //999</code>

你宣告的是一個全域變量,因為它是全域的,所以你在函數內或函數外都可以刪除它。
刪除後,無論你在函數內或外,它都不存在了。

注意:
函數內外的都是同一個變量,指向同一個指標。

宣告一個全域變數後,它並不會在函數內和函數外各創建一個變數。

補充:
我的理解有誤,樓下@咪蛾
說的:

<code>global $var1;等于$var1=&$GLOBALS['var1'];
</code>

是正確的。

再補充一下:
才發現之前自己沒有看清楚:

<code>global $var1;等于$var1=&$GLOBALS['var1'];
</code>

這句沒有錯,但我之前並沒有註意到&的存在。
因為去掉&的話好像比較好理解。
但事實上&是存在的,所以,還是跟我上邊說的一樣:裡外的$var1指向的是同一個地址。

讓我們再看回去例子:

<code>$var1 = 1; 
function test(){ 
    global $var1;                       
    unset($GLOBALS['var1']);
    echo $var1;
} 
test(); //1 已经删除了$var1,为什么函数内的$var1还存在呢?
echo $var1;//Undefined</code>

-->疑問:既然是同一個東西,為什麼一個有輸出,一個報錯呢?

換一個試試:
$var1 = 1;
function test(){

<code>global $var1;                       
$GLOBALS['var1']=99;
echo $var1;</code>

}
test(); //99
echo $var1;//99

-->改一個,另一個也同時改變,說明他們應該還是同一個東西吧?

所以,問題在哪裡呢?
其實問題出在unset()這個函數:

當你 unset 一個引用,只是斷開了變數名稱和變數內容之間的綁定。這並不意味著變數內容被銷毀了。

(參考:http://blog.csdn.net/ebw123/a...)

我現在初步找到了一點線索,看下面的程式碼:

範例1

<code><?php
function test(){            
    global $var;                       
    $var=999;
}
test(); 
echo $var;                //999
?></code>

範例2

<code><?php
function test(){            
    global $var;
    unset($GLOBALS['var']);                        
    $var=999;
}
test(); 
echo $var;                //错误
?>
</code>

範例3

<code>    <?php
    function test(){   
        unset($GLOBALS['var']);           
        global $var;              
        $var=999;
    }
    test(); 
    echo $var;                //999
    ?>
</code>

結合問題及本回應內容中的程式碼,總結如下
在函數內使用unset($GLOBALS['var']);

1:它會是函數外部的$var變數銷毀(因為$GLOBALS[ 'var']就是外部$var本身)

2:

  • 在函數內部如果在unset($GLOBALS['var']); 之前已經有global變數(可以被外部存取),那麼unset($GLOBALS['var']);會取消外部存取函數內global變量的"權利"

  • 在函數內部如果在unset($GLOBALS['var']); 之後已經有global變數(可以被外部存取),那麼unset($GLOBALS['var']);將不會干涉外部存取函數內global變數的"權利"

疑問:
除了unset($GLOBALS['var']); 可以銷毀外部變數$var,使其指向的zval的refcount的數量減一,

難道它還可以使原本在函數內的global變數的作用範圍從全局變成局部(導致外部無法存取函數內部global變數)?

希望,大神指點迷津。

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