Heim  >  Artikel  >  Backend-Entwicklung  >  关于PHP中global的问题

关于PHP中global的问题

WBOY
WBOYOriginal
2016-10-23 00:12:541459Durchsuche

各位大神中午好,我在网上看到了这么一个知识点:
函数内部声明的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>

你声明的是一个全局变量,因为它是全局的,所以你在函数内或者函数外都可以删除它。
删除后,无论你在函数内还是外,它都不存在了。

注意:
函数内外的都是同一个变量,指向同一个指针。

声明一个全局变量后,它并不会在函数内和函数外各创建一个变量。

补充:
我的理解有误,楼下@咪蛾
说的:

<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变量)?

希望,大神指点迷津。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn