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 相关文章推荐
用libTemplate实现静态网页的生成
Oct 09 PHP
一些常用的php简单命令代码集锦
Sep 24 PHP
PHP,ASP.JAVA,JAVA代码格式化工具整理
Jun 15 PHP
PHP实现手机归属地查询API接口实现代码
Aug 27 PHP
PHP中__FILE__、dirname与basename用法实例分析
Dec 01 PHP
kindeditor 加入七牛云上传的实例讲解
Nov 12 PHP
ThinkPHP5 验证器的具体使用
May 31 PHP
php 可变函数使用小结
Jun 12 PHP
Yii2.0 RESTful API 基础配置教程详解
Dec 26 PHP
php实现多站点共用session实现单点登录的方法详解
Sep 18 PHP
PHP实现通过二维数组键值获取一维键名操作示例
Oct 11 PHP
php实现统计IP数及在线人数的示例代码
Jul 22 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中的串行化变量和序列化对象
2006/09/05 PHP
基于ThinkPHP删除目录及目录文件函数
2020/10/28 PHP
ext实现完整的登录代码
2008/08/08 Javascript
javascript prototype 原型链
2009/03/12 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
Bootstrap零基础入门教程(三)
2016/07/18 Javascript
jQuery 的 ready()的纯js替代方法
2016/11/20 Javascript
浅谈jQuery before和insertBefore的区别
2016/12/04 Javascript
基于Cookie常用操作以及属性介绍
2017/09/07 Javascript
JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】
2018/05/07 Javascript
微信小程序Echarts图表组件使用方法详解
2019/06/25 Javascript
Python实现竖排打印传单手机号码易撕条
2015/03/16 Python
在Python程序中实现分布式进程的教程
2015/04/28 Python
python定时检查某个进程是否已经关闭的方法
2015/05/20 Python
Python编程实现二叉树及七种遍历方法详解
2017/06/02 Python
Python 解决中文写入Excel时抛异常的问题
2018/05/03 Python
Python3单行定义多个变量或赋值方法
2018/07/12 Python
python 快速把超大txt文件转存为csv的实例
2018/10/26 Python
使用Python实现微信提醒备忘录功能
2018/12/04 Python
Python3.5文件读与写操作经典实例详解
2019/05/01 Python
Django中的静态文件管理过程解析
2019/08/01 Python
Python 写入训练日志文件并控制台输出解析
2019/08/13 Python
Python二元赋值实用技巧解析
2019/10/25 Python
tensorflow 实现自定义梯度反向传播代码
2020/02/10 Python
利用CSS3的border-radius绘制太极及爱心图案示例
2016/05/17 HTML / CSS
浅谈css3中calc在less编译时被计算的解决办法
2017/12/04 HTML / CSS
html5的canvas实现3d雪花飘舞效果
2013/12/27 HTML / CSS
美国棒球装备和用品商店:Baseball Savings
2018/06/09 全球购物
美国家居装饰店:Z Gallerie
2020/12/28 全球购物
公司前台接待岗位职责
2013/12/03 职场文书
xxx同志考察材料
2014/02/07 职场文书
遗体告别仪式主持词
2014/03/20 职场文书
工作求职信
2014/07/04 职场文书
党的群众路线教育实践活动剖析材料
2014/09/30 职场文书
运动会加油稿30字
2015/07/21 职场文书