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_MySQL教程-第一天
Mar 18 PHP
PHP截取汉字乱码问题解决方法mb_substr函数的应用
Mar 30 PHP
PHP 页面跳转到另一个页面的多种方法方法总结
Jul 07 PHP
奉献出一个封装的curl函数 便于调用(抓数据专用)
Jul 22 PHP
将word转化为swf 如同百度文库般阅读实现思路及代码
Aug 09 PHP
ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单
May 15 PHP
Symfony数据校验方法实例分析
Jan 26 PHP
学习php设计模式 php实现装饰器模式(decorator)
Dec 07 PHP
php获取文件后缀的9种方法
Mar 22 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
PHP PDOStatement::bindColumn讲解
Jan 30 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
Dec 25 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连接MSSQL方法汇总
2016/02/05 PHP
PHP微信支付实例解析
2016/07/22 PHP
jQuery 性能优化指南 (1)
2009/05/21 Javascript
深入理解javascript学习笔记(一) 编写高质量代码
2012/08/09 Javascript
Javascript表格翻页效果实现思路及代码
2013/08/23 Javascript
查找Oracle高消耗语句的方法
2014/03/22 Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
2014/08/12 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
JS 打印功能代码可实现打印预览、打印设置等
2014/10/31 Javascript
基于jQuery实现的文字按钮表单特效整理
2014/12/07 Javascript
ECMAScript 5中的属性描述符详解
2015/03/02 Javascript
详解Windows下安装Nodejs步骤
2017/05/18 NodeJs
Vue中的混入的使用(vue mixins)
2018/06/01 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
2019/01/15 Javascript
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
Python创建模块及模块导入的方法
2015/05/27 Python
python获取当前用户的主目录路径方法(推荐)
2017/01/12 Python
ansible作为python模块库使用的方法实例
2017/01/17 Python
Python实现的弹球小游戏示例
2017/08/01 Python
解决pandas无法在pycharm中使用plot()方法显示图像的问题
2018/05/24 Python
python装饰器常见使用方法分析
2019/06/26 Python
Python参数类型以及常见的坑详解
2019/07/08 Python
ORM Django 终端打印 SQL 语句实现解析
2019/08/09 Python
Python Subprocess模块原理及实例
2019/08/26 Python
打包PyQt5应用时的注意事项
2020/02/14 Python
Python之字典添加元素的几种方法
2020/09/30 Python
澳大利亚婴儿、幼儿和儿童在线设计师商店:Smooch Baby
2019/02/16 全球购物
法国女性内衣购物网站:Glamuse
2019/05/13 全球购物
德国领先的大尺码和超大尺码男装在线零售商:Bigtex
2019/06/22 全球购物
同学会邀请书大全
2014/01/12 职场文书
安踏广告词改编版
2014/03/21 职场文书
酒店餐厅2014重阳节活动策划方案
2014/09/16 职场文书
代理人委托书
2014/09/16 职场文书
2015年科学教研组工作总结
2015/07/22 职场文书
2021年最新用于图像处理的Python库总结
2021/06/15 Python
星际争霸 Light vs Action 一场把教主看到鬼畜的比赛
2022/04/01 星际争霸