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的控制语句
Oct 09 PHP
mysqli_set_charset和SET NAMES使用抉择及优劣分析
Jan 13 PHP
php 发送带附件邮件示例
Jan 23 PHP
PHP生成短网址的3种方法代码实例
Jul 08 PHP
Yii框架中 find findAll 查找出制定的字段的方法对比
Sep 10 PHP
php通过记录IP来防止表单重复提交方法分析
Dec 16 PHP
简单谈谈php中的unicode和utf8编码
Jun 10 PHP
php实现json编码的方法
Jul 30 PHP
Laravel5中Cookie的使用详解
May 03 PHP
PHP实现获取第一个中文首字母并进行排序的方法
May 09 PHP
详解PHP处理字符串类似indexof的方法函数
Jun 11 PHP
imagettftext() 失效,不起作用
Mar 09 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
PHP无限分类的类
2007/01/02 PHP
php htmlspecialchars()与shtmlspecialchars()函数的深入分析
2013/06/05 PHP
PHP中date与gmdate的区别及默认时区设置
2014/05/12 PHP
php获得文件夹下所有文件的递归算法的简单实例
2016/11/01 PHP
Laravel学习教程之IOC容器的介绍与用例
2017/08/15 PHP
laravel 使用事件系统统计浏览量的实现
2019/10/16 PHP
PHP解密支付宝小程序的加密数据、手机号的示例代码
2021/02/26 PHP
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
javascript组合使用构造函数模式和原型模式实例
2015/06/04 Javascript
javascript深拷贝的原理与实现方法分析
2017/04/10 Javascript
JS中使用gulp实现压缩文件及浏览器热加载功能
2017/07/12 Javascript
vue基于mint-ui实现城市选择三级联动
2020/06/30 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
2020/07/11 Javascript
[02:15]2015国际邀请赛选手档案IG.Ferrari 430
2015/07/30 DOTA
[01:35:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第一场 1月18日
2021/03/11 DOTA
python统计多维数组的行数和列数实例
2018/06/23 Python
Python 给某个文件名添加时间戳的方法
2018/10/16 Python
python贪吃蛇游戏代码
2020/04/18 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
Python3查找列表中重复元素的个数的3种方法详解
2020/02/13 Python
基于Python3读写INI配置文件过程解析
2020/07/23 Python
Python模块常用四种安装方式
2020/10/20 Python
Python爬虫中Selenium实现文件上传
2020/12/04 Python
印尼最大的婴儿用品购物网站:Orami
2017/09/28 全球购物
迪卡侬荷兰官网:Decathlon荷兰
2017/10/29 全球购物
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
档案管理员岗位职责
2013/12/01 职场文书
董事长秘书职责
2014/01/31 职场文书
颁奖典礼主持词
2014/03/25 职场文书
药店促销活动策划方案
2014/08/24 职场文书
安全生产月标语
2014/10/07 职场文书
初三语文教学计划
2015/01/22 职场文书
2015年中学校长工作总结
2015/05/19 职场文书
三国演义读书笔记
2015/06/25 职场文书
关于考试抄袭的检讨书
2019/11/02 职场文书