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中定义网站根目录的常用方法
Aug 08 PHP
仿AS3实现PHP 事件机制实现代码
Jan 27 PHP
php引用地址改变变量值的问题
Mar 23 PHP
浅析PHP递归函数返回值使用方法
Feb 18 PHP
php gzip压缩输出的实现方法
Apr 27 PHP
phpmyadmin配置文件现在需要绝密的短密码(blowfish_secret)的2种解决方法
May 07 PHP
PHP中file_get_contents高?用法实例
Sep 24 PHP
php使用glob函数快速查询指定目录文件的方法
Nov 15 PHP
分享常见的几种页面静态化的方法
Jan 08 PHP
PHP中ltrim与rtrim去除左右空格及特殊字符实例
Jan 07 PHP
详谈PHP中的密码安全性Password Hashing
Feb 04 PHP
原生PHP实现导出csv格式Excel文件的方法示例【附源码下载】
Mar 07 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
js和php邮箱地址验证的实现方法
2014/01/09 PHP
PHP检测用户语言的方法
2015/06/15 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
2016/12/27 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
Laravel 队列使用的实现
2019/01/08 PHP
php获取是星期几的的一些常用姿势
2019/12/15 PHP
JavaScript设置FieldSet展开与收缩
2009/05/15 Javascript
jQuery 改变CSS样式基础代码
2010/02/11 Javascript
基于jquery实现的可以编辑选择的下拉框的代码
2010/11/19 Javascript
jquery异步调用页面后台方法&amp;#8207;(asp.net)
2011/03/01 Javascript
js opener的使用详解
2014/01/11 Javascript
Ext4.2的Ext.grid.plugin.RowExpander无法触发事件解决办法
2014/08/15 Javascript
javascript学习总结之js使用技巧
2015/09/02 Javascript
JavaScript判断按钮被点击的方法
2015/12/13 Javascript
第九篇Bootstrap导航菜单创建步骤详解
2016/06/21 Javascript
AngularJs定制样式插入到ueditor中的问题小结
2016/08/01 Javascript
基于 webpack2 实现的多入口项目脚手架详解
2017/06/26 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
js中怎么判断两个字符串相等的实例
2019/01/17 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变opacity实现)
2019/01/24 Javascript
vue中axios防止多次触发终止多次请求的示例代码(防抖)
2020/02/16 Javascript
python类和继承用法实例
2015/07/07 Python
使用Python神器对付12306变态验证码
2016/01/05 Python
Python 爬虫学习笔记之正则表达式
2016/09/21 Python
Python使用matplotlib简单绘图示例
2018/02/01 Python
在Pycharm中项目解释器与环境变量的设置方法
2018/10/29 Python
Python程序控制语句用法实例分析
2020/01/14 Python
Python日志器使用方法及原理解析
2020/09/27 Python
使用CSS3创建动态菜单效果
2015/07/10 HTML / CSS
EJB实例的生命周期
2016/10/28 面试题
公积金转移接收函
2014/01/11 职场文书
校运动会广播稿300字
2014/10/07 职场文书
高三英语教学计划
2015/01/23 职场文书
身份证丢失证明
2015/06/19 职场文书
frg-100简单操作(设置)说明
2022/04/05 无线电
Java版 单机五子棋
2022/05/04 Java/Android