PHP语言中global和$GLOBALS[]的分析 之二


Posted in PHP onFebruary 02, 2012

还是借用上一篇的例子:

PHP代码

<?php 
// 例子1 
function test_global() { 
global $var1, $var2; 
$var2 =& $var1; 
} 
function test_globals() { 
$GLOBALS['var3'] =& $GLOBALS['var1']; 
} 
$var1 = 5; 
$var2 = $var3 = 0; 
test_global(); 
print $var2 .”\n”; 
test_globals(); 
print $var3 .”\n”; 
?>

执行结果为:
0
5
怎么会这样呢?不应该是2个5吗?怎么会出现1个0和1个5呢?

恩,我们保留以上问题,深入分析$GLOBALS和global的原理!
我们都知道变量其实是相应物理内存在代码中的”代号”而已
引用php手册的$GLOBALS的解释:
Global 变量:$GLOBALS,注意: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。
由所有已定义全局变量组成的数组。变量名就是该数组的索引。这是一个“superglobal”,或者可以描述为自动全局变量。
也就是说上面代码中的$var1和$GLOBALS['var1']是指的同一变量,而不是2个不同的变量!
下面来分析global到底做了什么?
引用php手册的global的解释:
如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见。可以通过使用 $GLOBALS 数组避免这一点。
我们都知道php中的函数所产生的变量都是函数的私有变量,那么global关键字产生的变量也肯定逃不出这个规则,为什么这么说呢,看下面的代码:
PHP代码

<?php 
// 例子2 
function test() { 
global $a; 
unset($a); 
} 
$a = 1; 
test(); 
print $a; 
?>

执行结果为:
1
为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug?
都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数test()中加入
print $a;
来测试!
接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化只在函数的局部产生效应,在函数外部$var2的指向物理内存地址并没有变化,还是它自己.
此时,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了!
所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于:
global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况,例如例子 1.
$GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致
可以对照 下面两个列子再加深下印象:
global:
<?php 
function myfunction(){ 
global $bar; 
unset($bar); 
} 
$bar=”someting”; 
myfunction(); 
echo $bar; 
?>

输出:someting
$GLOBALS[]:
<?php 
function foo() 
{ 
unset($GLOBALS['bar']); 
} 
$bar = “something”; 
foo(); 
echo $bar; 
?>

输出:空
当按照上面的思路理解后,碰到下面的情况是不是又有些晕呢?
<?php 
$a = 1; 
$b = 2; 
function Sum() 
{ 
global $a, $b; 
$b = $a + $b; 
} 
Sum(); 
echo $b; 
?>

输出将是 “3″。在函数中申明 了全局变量 $a 和 $b,任何变量的所有引用变量都会指向到全局变量。
怎么不是2呢,在函数外部不是不影响吗,请注意$b在函数中并没有通过引用修改,而是修改的$b指向物理内存的值,因此外部输入为3。
PHP 相关文章推荐
PHP中Date获取时间不正确怎么办
Jun 05 PHP
php中配置文件操作 如config.php文件的读取修改等操作
Jul 07 PHP
phpadmin如何导入导出大数据文件及php.ini参数修改
Feb 18 PHP
PHP中的按位与和按位或操作示例
Jan 27 PHP
php curl登陆qq后获取用户信息时证书错误
Feb 03 PHP
PHP实现根据时间戳获取周几的方法
Feb 26 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
Mar 03 PHP
浅析Yii2中GridView常见操作
Apr 22 PHP
PHP数组编码gbk与utf8互相转换的两种方法
Sep 01 PHP
ThinkPHP发送邮件示例代码
Oct 08 PHP
AES加解密在php接口请求过程中的应用示例
Oct 26 PHP
laravel高级的Join语法详解以及使用Join多个条件
Oct 16 PHP
php中global和$GLOBALS[]的分析之一
Feb 02 #PHP
PHP开发者常犯的10个MySQL错误更正剖析
Jan 30 #PHP
PHP中全面阻止SQL注入式攻击分析小结
Jan 30 #PHP
几种有用的变型 PHP中循环语句的用法介绍
Jan 30 #PHP
通过PHP修改Linux或Unix口令的方法分享
Jan 30 #PHP
php代码收集表单内容并写入文件的代码
Jan 29 #PHP
php 无法加载mysql的module的时候的配置的解决方案引发的思考
Jan 27 #PHP
You might like
中国收音机工业发展史
2021/03/02 无线电
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
2010/10/12 PHP
探讨PHP JSON中文乱码的解决方法详解
2013/06/06 PHP
php使用ZipArchive函数实现文件的压缩与解压缩
2015/10/27 PHP
php连接oracle数据库的核心步骤
2016/05/26 PHP
thinkphp中多表查询中防止数据重复的sql语句(必看)
2016/09/22 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
php 中的closure用法详解
2017/06/12 PHP
yii2局部关闭(开启)csrf的验证的实例代码
2017/07/10 PHP
php实现记事本案例
2020/10/20 PHP
客户端脚本中常常出现的一些问题和调试技巧
2007/01/09 Javascript
Javascript模块化编程(一)模块的写法最佳实践
2013/01/17 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
2014/06/05 Javascript
jQuery实现购物车计算价格功能的方法
2015/03/25 Javascript
jQuery基于muipicker实现仿ios时间选择
2016/02/22 Javascript
jquery trigger函数执行两次的解决方法
2016/02/29 Javascript
javascript实现简单计算器效果【推荐】
2016/04/19 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
2017/11/20 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
JS脚本加载后执行相应回调函数的操作方法
2018/02/28 Javascript
详解vue中使用微信jssdk
2019/04/19 Javascript
配置一个vue3.0项目的完整步骤
2019/04/26 Javascript
AngularJs中$cookies简单用法分析
2019/05/30 Javascript
[46:21]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
python实现提取百度搜索结果的方法
2015/05/19 Python
Python人脸识别初探
2017/12/21 Python
Python3中编码与解码之Unicode与bytes的讲解
2019/02/28 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
css3模拟jq点击事件的实例代码
2017/07/06 HTML / CSS
入党积极分子自我鉴定
2014/02/18 职场文书
电子商务专业毕业生求职信
2014/06/12 职场文书
大学军训自我鉴定大全
2014/09/18 职场文书
会计人员岗位职责
2015/02/03 职场文书
收银员岗位职责
2015/02/03 职场文书
导游词之潮音寺
2019/09/26 职场文书
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
2021/04/12 Python