各位大神中午好,我在網路上看到了這麼一個知識點:
函數內部聲明的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變數)?
希望,大神指點迷津。